aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tests/wpt/meta-legacy-layout/css/CSS2/linebox/inline-negative-margin-001.html.ini5
-rw-r--r--tests/wpt/meta-legacy-layout/css/css-color/system-color-support.html.ini57
-rw-r--r--tests/wpt/meta-legacy-layout/css/css-color/t32-opacity-basic-0.6-a.xht.ini2
-rw-r--r--tests/wpt/meta-legacy-layout/css/css-fonts/animations/font-palette-animation-not-specified-endpoints.html.ini7
-rw-r--r--tests/wpt/meta-legacy-layout/css/css-images/parsing/gradient-interpolation-method-computed.html.ini6
-rw-r--r--tests/wpt/meta-legacy-layout/css/css-text/inheritance.html.ini12
-rw-r--r--tests/wpt/meta-legacy-layout/css/css-text/parsing/text-wrap-computed.html.ini66
-rw-r--r--tests/wpt/meta-legacy-layout/css/css-text/parsing/text-wrap-mode-computed.html.ini6
-rw-r--r--tests/wpt/meta-legacy-layout/css/css-text/parsing/text-wrap-mode-valid.html.ini21
-rw-r--r--tests/wpt/meta-legacy-layout/css/css-text/parsing/text-wrap-style-computed.html.ini12
-rw-r--r--tests/wpt/meta-legacy-layout/css/css-text/parsing/text-wrap-style-valid.html.ini27
-rw-r--r--tests/wpt/meta-legacy-layout/css/css-values/round-mod-rem-computed.html.ini9
-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/fetch/fetch-later/headers/header-referrer-no-referrer-when-downgrade.tentative.https.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/fetch/fetch-later/headers/header-referrer-no-referrer.tentative.https.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/fetch/fetch-later/headers/header-referrer-origin-when-cross-origin.tentative.https.html.ini6
-rw-r--r--tests/wpt/meta-legacy-layout/fetch/fetch-later/headers/header-referrer-origin.tentative.https.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/fetch/fetch-later/headers/header-referrer-same-origin.tentative.https.html.ini6
-rw-r--r--tests/wpt/meta-legacy-layout/fetch/fetch-later/headers/header-referrer-strict-origin-when-cross-origin.tentative.https.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/fetch/fetch-later/headers/header-referrer-strict-origin.tentative.https.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/fetch/fetch-later/headers/header-referrer-unsafe-url.tentative.https.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/fetch/fetch-later/iframe.tentative.https.window.js.ini2
-rw-r--r--tests/wpt/meta-legacy-layout/fetch/fetch-later/new-window.tentative.https.window.js.ini2
-rw-r--r--tests/wpt/meta-legacy-layout/fetch/fetch-later/policies/csp-allowed.tentative.https.window.js.ini2
-rw-r--r--tests/wpt/meta-legacy-layout/fetch/fetch-later/policies/csp-blocked.tentative.https.window.js.ini2
-rw-r--r--tests/wpt/meta-legacy-layout/fetch/fetch-later/policies/csp-redirect-to-blocked.tentative.https.window.js.ini2
-rw-r--r--tests/wpt/meta-legacy-layout/fetch/metadata/generated/css-images.sub.tentative.html.ini9
-rw-r--r--tests/wpt/meta-legacy-layout/hr-time/raf-coarsened-time.https.html.ini2
-rw-r--r--tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/order-in-bfcache-restore.html.ini4
-rw-r--r--tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/order-in-new-document-navigation.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/order-in-prerender-activation.html.ini2
-rw-r--r--tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/iframe-src-aboutblank-navigate-immediately.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/load-pageshow-events-iframe-contentWindow.html.ini6
-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/canvas/element/manual/drawing-text-to-the-canvas/canvas.2d.disconnected-font-size-math.html.ini2
-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/dom/elements/global-attributes/dir-auto-form-associated.window.js.ini66
-rw-r--r--tests/wpt/meta-legacy-layout/html/dom/elements/global-attributes/lang-attribute.window.js.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-1.html.ini1
-rw-r--r--tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-2.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-3.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-img-element/non-active-document.html.ini6
-rw-r--r--tests/wpt/meta-legacy-layout/html/semantics/forms/form-submission-0/text-plain.window.js.ini6
-rw-r--r--tests/wpt/meta-legacy-layout/html/semantics/forms/historical.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/semantics/invokers/invokeelement-interface.tentative.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_noopener.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/semantics/scripting-1/the-script-element/defer-script/async-script.html.ini4
-rw-r--r--tests/wpt/meta-legacy-layout/html/syntax/parsing/DOMContentLoaded-defer.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-job-queue/promise-job-entry-different-function-realm.html.ini5
-rw-r--r--tests/wpt/meta-legacy-layout/html/webappapis/scripting/processing-model-2/unhandled-promise-rejections/promise-rejection-events.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/wasm/jsapi/gc/casts.tentative.any.js.ini5
-rw-r--r--tests/wpt/meta-legacy-layout/wasm/jsapi/gc/exported-object.tentative.any.js.ini5
-rw-r--r--tests/wpt/meta-legacy-layout/wasm/jsapi/gc/i31.tentative.any.js.ini5
-rw-r--r--tests/wpt/meta-legacy-layout/webmessaging/with-ports/018.html.ini4
-rw-r--r--tests/wpt/meta-legacy-layout/webmessaging/without-ports/017.html.ini4
-rw-r--r--tests/wpt/meta-legacy-layout/webstorage/localstorage-about-blank-3P-iframe-opens-3P-window.partitioned.tentative.html.ini4
-rw-r--r--tests/wpt/meta/MANIFEST.json2258
-rw-r--r--tests/wpt/meta/css/CSS2/linebox/inline-negative-margin-001.html.ini15
-rw-r--r--tests/wpt/meta/css/css-color/system-color-support.html.ini57
-rw-r--r--tests/wpt/meta/css/css-fonts/animations/font-palette-animation-not-specified-endpoints.html.ini7
-rw-r--r--tests/wpt/meta/css/css-fonts/variations/at-font-face-font-matching.html.ini66
-rw-r--r--tests/wpt/meta/css/css-images/parsing/gradient-interpolation-method-computed.html.ini6
-rw-r--r--tests/wpt/meta/css/css-text/inheritance.html.ini12
-rw-r--r--tests/wpt/meta/css/css-text/parsing/text-wrap-computed.html.ini66
-rw-r--r--tests/wpt/meta/css/css-text/parsing/text-wrap-mode-computed.html.ini6
-rw-r--r--tests/wpt/meta/css/css-text/parsing/text-wrap-mode-valid.html.ini21
-rw-r--r--tests/wpt/meta/css/css-text/parsing/text-wrap-style-computed.html.ini12
-rw-r--r--tests/wpt/meta/css/css-text/parsing/text-wrap-style-valid.html.ini27
-rw-r--r--tests/wpt/meta/css/css-values/round-mod-rem-computed.html.ini9
-rw-r--r--tests/wpt/meta/fetch/api/redirect/redirect-keepalive.any.js.ini1
-rw-r--r--tests/wpt/meta/fetch/fetch-later/headers/header-referrer-no-referrer-when-downgrade.tentative.https.html.ini3
-rw-r--r--tests/wpt/meta/fetch/fetch-later/headers/header-referrer-no-referrer.tentative.https.html.ini3
-rw-r--r--tests/wpt/meta/fetch/fetch-later/headers/header-referrer-origin-when-cross-origin.tentative.https.html.ini6
-rw-r--r--tests/wpt/meta/fetch/fetch-later/headers/header-referrer-origin.tentative.https.html.ini3
-rw-r--r--tests/wpt/meta/fetch/fetch-later/headers/header-referrer-same-origin.tentative.https.html.ini6
-rw-r--r--tests/wpt/meta/fetch/fetch-later/headers/header-referrer-strict-origin-when-cross-origin.tentative.https.html.ini3
-rw-r--r--tests/wpt/meta/fetch/fetch-later/headers/header-referrer-strict-origin.tentative.https.html.ini3
-rw-r--r--tests/wpt/meta/fetch/fetch-later/headers/header-referrer-unsafe-url.tentative.https.html.ini3
-rw-r--r--tests/wpt/meta/fetch/fetch-later/iframe.tentative.https.window.js.ini2
-rw-r--r--tests/wpt/meta/fetch/fetch-later/new-window.tentative.https.window.js.ini2
-rw-r--r--tests/wpt/meta/fetch/fetch-later/policies/csp-allowed.tentative.https.window.js.ini2
-rw-r--r--tests/wpt/meta/fetch/fetch-later/policies/csp-blocked.tentative.https.window.js.ini2
-rw-r--r--tests/wpt/meta/fetch/fetch-later/policies/csp-redirect-to-blocked.tentative.https.window.js.ini2
-rw-r--r--tests/wpt/meta/fetch/metadata/generated/css-images.sub.tentative.html.ini3
-rw-r--r--tests/wpt/meta/hr-time/raf-coarsened-time.https.html.ini2
-rw-r--r--tests/wpt/meta/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/order-in-bfcache-restore.html.ini4
-rw-r--r--tests/wpt/meta/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/order-in-new-document-navigation.html.ini3
-rw-r--r--tests/wpt/meta/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/order-in-prerender-activation.html.ini2
-rw-r--r--tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/load-pageshow-events-iframe-contentWindow.html.ini4
-rw-r--r--tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/load-pageshow-events-window-open.html.ini3
-rw-r--r--tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/javascript-url-return-value-handling-dynamic.html.ini12
-rw-r--r--tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-cross-origin.sub.window.js.ini3
-rw-r--r--tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-same-origin.window.js.ini3
-rw-r--r--tests/wpt/meta/html/browsers/browsing-the-web/overlapping-navigations-and-traversals/nav-cancelation-2.sub.html.ini3
-rw-r--r--tests/wpt/meta/html/browsers/history/the-history-interface/traverse-during-unload.html.ini4
-rw-r--r--tests/wpt/meta/html/browsers/history/the-history-interface/traverse_the_history_5.html.ini (renamed from tests/wpt/meta-legacy-layout/html/browsers/history/the-history-interface/traverse_the_history_5.html.ini)0
-rw-r--r--tests/wpt/meta/html/browsers/origin/cross-origin-objects/cross-origin-objects.html.ini1
-rw-r--r--tests/wpt/meta/html/browsers/the-window-object/open-close/creating_browsing_context_test_01.html.ini (renamed from tests/wpt/meta-legacy-layout/html/browsers/the-window-object/open-close/creating_browsing_context_test_01.html.ini)0
-rw-r--r--tests/wpt/meta/html/browsers/windows/embedded-opener-remove-frame.html.ini2
-rw-r--r--tests/wpt/meta/html/dom/elements/global-attributes/dir-auto-form-associated.window.js.ini66
-rw-r--r--tests/wpt/meta/html/dom/elements/global-attributes/lang-attribute.window.js.ini3
-rw-r--r--tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-1.html.ini3
-rw-r--r--tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html.ini3
-rw-r--r--tests/wpt/meta/html/semantics/embedded-content/the-img-element/non-active-document.html.ini6
-rw-r--r--tests/wpt/meta/html/semantics/invokers/invokeelement-interface.tentative.html.ini3
-rw-r--r--tests/wpt/meta/html/webappapis/dynamic-markup-insertion/document-write/module-static-import-delayed.html.ini3
-rw-r--r--tests/wpt/meta/html/webappapis/scripting/events/compile-event-handler-settings-objects.html.ini3
-rw-r--r--tests/wpt/meta/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-job-queue/promise-job-entry-different-function-realm.html.ini5
-rw-r--r--tests/wpt/meta/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-job-queue/promise-job-entry.html.ini5
-rw-r--r--tests/wpt/meta/resource-timing/content-type-parsing.html.ini4
-rw-r--r--tests/wpt/meta/wasm/jsapi/functions/entry.html.ini3
-rw-r--r--tests/wpt/meta/wasm/jsapi/gc/casts.tentative.any.js.ini5
-rw-r--r--tests/wpt/meta/wasm/jsapi/gc/exported-object.tentative.any.js.ini5
-rw-r--r--tests/wpt/meta/wasm/jsapi/gc/i31.tentative.any.js.ini5
-rw-r--r--tests/wpt/meta/webmessaging/with-ports/017.html.ini4
-rw-r--r--tests/wpt/meta/webmessaging/with-ports/018.html.ini4
-rw-r--r--tests/wpt/meta/webmessaging/without-ports/018.html.ini4
-rw-r--r--tests/wpt/meta/workers/constructors/Worker/Worker-constructor.html.ini2
-rw-r--r--tests/wpt/tests/.github/workflows/documentation.yml2
-rw-r--r--tests/wpt/tests/accelerometer/Accelerometer-iframe-access.https.html9
-rw-r--r--tests/wpt/tests/accelerometer/Accelerometer.https.html26
-rw-r--r--tests/wpt/tests/accelerometer/GravitySensor.https.html22
-rw-r--r--tests/wpt/tests/accelerometer/LinearAccelerationSensor.https.html22
-rw-r--r--tests/wpt/tests/accelerometer/resources/sensor-data.js34
-rw-r--r--tests/wpt/tests/ambient-light/AmbientLightSensor-iframe-access.https.html5
-rw-r--r--tests/wpt/tests/ambient-light/AmbientLightSensor.https.html56
-rw-r--r--tests/wpt/tests/ambient-light/resources/sensor-data.js47
-rw-r--r--tests/wpt/tests/clipboard-apis/clipboard-item.https.html14
-rw-r--r--tests/wpt/tests/close-watcher/closewatcher-dialog-popover.html10
-rw-r--r--tests/wpt/tests/close-watcher/dialog-cancel-events-closewatcher.html55
-rw-r--r--tests/wpt/tests/close-watcher/dialog-cancel-preventDefault-closewatcher.html55
-rw-r--r--tests/wpt/tests/close-watcher/resources/helpers.js32
-rw-r--r--tests/wpt/tests/close-watcher/user-activation-shared.html16
-rw-r--r--tests/wpt/tests/common/top-layer.js29
-rw-r--r--tests/wpt/tests/content-security-policy/resource-hints/prefetch-generate-directives.html1
-rw-r--r--tests/wpt/tests/credential-management/fedcm-domainhint.https.html (renamed from tests/wpt/tests/credential-management/fedcm-hosteddomain.https.html)20
-rw-r--r--tests/wpt/tests/credential-management/fedcm-endpoint-redirects.https.html10
-rw-r--r--tests/wpt/tests/credential-management/fedcm-error-basic.https.html34
-rw-r--r--tests/wpt/tests/credential-management/fedcm-login-status/cross-origin-status.https.html10
-rw-r--r--tests/wpt/tests/credential-management/fedcm-store.https.html19
-rw-r--r--tests/wpt/tests/credential-management/fedcm-token-returned-with-http-error.https.html23
-rw-r--r--tests/wpt/tests/credential-management/otpcredential-store.https.html17
-rw-r--r--tests/wpt/tests/credential-management/support/fedcm-helper.sub.js52
-rw-r--r--tests/wpt/tests/credential-management/support/fedcm-mock.js19
-rw-r--r--tests/wpt/tests/credential-management/support/fedcm/accounts.py2
-rw-r--r--tests/wpt/tests/credential-management/support/fedcm/error_with_code_and_url.py12
-rw-r--r--tests/wpt/tests/credential-management/support/fedcm/manifest_id_assertion_endpoint_returns_error.json6
-rw-r--r--tests/wpt/tests/credential-management/support/fedcm/manifest_token_with_http_error.json6
-rw-r--r--tests/wpt/tests/credential-management/support/fedcm/token_with_http_error.py12
-rw-r--r--tests/wpt/tests/credential-management/support/fedcm/two_accounts.py2
-rw-r--r--tests/wpt/tests/credential-management/support/fencedframe-mark-signedin.html15
-rw-r--r--tests/wpt/tests/credential-management/support/iframe-mark-signedin.html4
-rw-r--r--tests/wpt/tests/credential-management/support/mark_signedin.sub.headers1
-rw-r--r--tests/wpt/tests/credential-management/support/mark_signedout.sub.headers1
-rw-r--r--tests/wpt/tests/css/css-color/lch-009.html4
-rw-r--r--tests/wpt/tests/css/css-color/lch-010.html4
-rw-r--r--tests/wpt/tests/css/css-color/nested-color-mix-with-currentcolor.html2
-rw-r--r--tests/wpt/tests/css/css-color/oklch-009.html4
-rw-r--r--tests/wpt/tests/css/css-color/oklch-010.html4
-rw-r--r--tests/wpt/tests/css/css-color/parsing/color-computed-color-mix-function.html4
-rw-r--r--tests/wpt/tests/css/css-color/system-color-support.html74
-rw-r--r--tests/wpt/tests/css/css-color/t32-opacity-basic-0.6-a-ref.html12
-rw-r--r--tests/wpt/tests/css/css-color/t32-opacity-basic-0.6-a-ref.xht18
-rw-r--r--tests/wpt/tests/css/css-color/t32-opacity-basic-0.6-a.xht13
-rw-r--r--tests/wpt/tests/css/css-color/t422-rgba-a0.6-a-ref.xht18
-rw-r--r--tests/wpt/tests/css/css-color/t422-rgba-a0.6-a.xht18
-rw-r--r--tests/wpt/tests/css/css-color/t425-hsla-basic-a-ref.html11
-rw-r--r--tests/wpt/tests/css/css-color/t425-hsla-basic-a-ref.xht17
-rw-r--r--tests/wpt/tests/css/css-color/t425-hsla-basic-a.xht20
-rw-r--r--tests/wpt/tests/css/css-color/xyz-d50-003-ref.html2
-rw-r--r--tests/wpt/tests/css/css-color/xyz-d50-003.html2
-rw-r--r--tests/wpt/tests/css/css-color/xyz-d50-004-ref.html2
-rw-r--r--tests/wpt/tests/css/css-color/xyz-d50-004.html2
-rw-r--r--tests/wpt/tests/css/css-fonts/animations/font-palette-animation-not-specified-endpoints.html67
-rw-r--r--tests/wpt/tests/css/css-fonts/animations/font-palette-interpolation.html4
-rw-r--r--tests/wpt/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-002.html2
-rw-r--r--tests/wpt/tests/css/css-images/parsing/gradient-interpolation-method-computed.html6
-rw-r--r--tests/wpt/tests/css/css-lists/dynamic-counters-crash.html39
-rw-r--r--tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-ellipse-mixed-change.html38
-rw-r--r--tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-ellipse-ref.html15
-rw-r--r--tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-ellipse.html34
-rw-r--r--tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-font-size-inherited.html38
-rw-r--r--tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-font-size-mixed-change.html46
-rw-r--r--tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-font-size-ref.html16
-rw-r--r--tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-font-size.html35
-rw-r--r--tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-path-ref.html15
-rw-r--r--tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-path.html35
-rw-r--r--tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-polygon-mixed-change.html38
-rw-r--r--tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-polygon-ref.html15
-rw-r--r--tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-polygon.html34
-rw-r--r--tests/wpt/tests/css/css-masking/mask-image/mask-image-3b.html1
-rw-r--r--tests/wpt/tests/css/css-masking/mask-image/mask-image-3c.html1
-rw-r--r--tests/wpt/tests/css/css-masking/mask-image/mask-image-3d.html1
-rw-r--r--tests/wpt/tests/css/css-masking/mask-image/mask-image-3e.html1
-rw-r--r--tests/wpt/tests/css/css-masking/mask-image/mask-image-3f.html1
-rw-r--r--tests/wpt/tests/css/css-masking/mask-image/mask-image-3g.html1
-rw-r--r--tests/wpt/tests/css/css-masking/parsing/mask-computed.html94
-rw-r--r--tests/wpt/tests/css/css-masking/parsing/mask-valid.sub.html6
-rw-r--r--tests/wpt/tests/css/css-properties-values-api/animation/custom-property-animation-transform-list-multiple-values.html4
-rw-r--r--tests/wpt/tests/css/css-properties-values-api/animation/custom-property-animation-transform-none.tentative.html30
-rw-r--r--tests/wpt/tests/css/css-properties-values-api/animation/custom-property-transition-transform-function-box-size.tentative.html19
-rw-r--r--tests/wpt/tests/css/css-properties-values-api/animation/custom-property-transition-transform-function-matrix.html17
-rw-r--r--tests/wpt/tests/css/css-properties-values-api/animation/custom-property-transition-transform-function-none.tentative.html18
-rw-r--r--tests/wpt/tests/css/css-properties-values-api/animation/custom-property-transition-transform-function-to-list.html17
-rw-r--r--tests/wpt/tests/css/css-properties-values-api/animation/custom-property-transition-transform-list-box-size.tentative.html19
-rw-r--r--tests/wpt/tests/css/css-properties-values-api/animation/custom-property-transition-transform-list-matrix.html17
-rw-r--r--tests/wpt/tests/css/css-properties-values-api/animation/custom-property-transition-transform-list-none.tentative.html18
-rw-r--r--tests/wpt/tests/css/css-properties-values-api/resources/utils.js3
-rw-r--r--tests/wpt/tests/css/css-scoping/chrome-1492368-crash.html17
-rw-r--r--tests/wpt/tests/css/css-scroll-anchoring/after-scrollable-range-shrinkage-003.html39
-rw-r--r--tests/wpt/tests/css/css-scroll-anchoring/after-scrollable-range-shrinkage-004.html45
-rw-r--r--tests/wpt/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-aligns-with-snap-align.tentative.html74
-rw-r--r--tests/wpt/tests/css/css-text/crashtests/text-indent-each-line-crash.html14
-rw-r--r--tests/wpt/tests/css/css-text/inheritance.html2
-rw-r--r--tests/wpt/tests/css/css-text/parsing/text-wrap-computed.html43
-rw-r--r--tests/wpt/tests/css/css-text/parsing/text-wrap-mode-computed.html20
-rw-r--r--tests/wpt/tests/css/css-text/parsing/text-wrap-mode-invalid.html35
-rw-r--r--tests/wpt/tests/css/css-text/parsing/text-wrap-mode-valid.html25
-rw-r--r--tests/wpt/tests/css/css-text/parsing/text-wrap-style-computed.html22
-rw-r--r--tests/wpt/tests/css/css-text/parsing/text-wrap-style-invalid.html29
-rw-r--r--tests/wpt/tests/css/css-text/parsing/text-wrap-style-valid.html27
-rw-r--r--tests/wpt/tests/css/css-values/round-mod-rem-computed.html4
-rw-r--r--tests/wpt/tests/css/cssom-view/checkVisibility.html6
-rw-r--r--tests/wpt/tests/css/cssom/insert-dir-rule-crash.html14
-rw-r--r--tests/wpt/tests/css/selectors/dir-pseudo-on-input-element.html7
-rw-r--r--tests/wpt/tests/domxpath/001.html60
-rw-r--r--tests/wpt/tests/domxpath/002.html60
-rw-r--r--tests/wpt/tests/domxpath/text-html-attributes.html102
-rw-r--r--tests/wpt/tests/domxpath/text-html-elements.html87
-rw-r--r--tests/wpt/tests/editing/data/formatblock.js342
-rw-r--r--tests/wpt/tests/editing/edit-context/edit-context-input.tentative.html2
-rw-r--r--tests/wpt/tests/fetch/fetch-later/headers/header-referrer-no-referrer-when-downgrade.tentative.https.html23
-rw-r--r--tests/wpt/tests/fetch/fetch-later/headers/header-referrer-no-referrer.tentative.https.html19
-rw-r--r--tests/wpt/tests/fetch/fetch-later/headers/header-referrer-origin-when-cross-origin.tentative.https.html25
-rw-r--r--tests/wpt/tests/fetch/fetch-later/headers/header-referrer-origin.tentative.https.html23
-rw-r--r--tests/wpt/tests/fetch/fetch-later/headers/header-referrer-same-origin.tentative.https.html24
-rw-r--r--tests/wpt/tests/fetch/fetch-later/headers/header-referrer-strict-origin-when-cross-origin.tentative.https.html24
-rw-r--r--tests/wpt/tests/fetch/fetch-later/headers/header-referrer-strict-origin.tentative.https.html24
-rw-r--r--tests/wpt/tests/fetch/fetch-later/headers/header-referrer-unsafe-url.tentative.https.html24
-rw-r--r--tests/wpt/tests/fetch/fetch-later/iframe.tentative.https.window.js65
-rw-r--r--tests/wpt/tests/fetch/fetch-later/new-window.tentative.https.window.js77
-rw-r--r--tests/wpt/tests/fetch/fetch-later/policies/csp-allowed.tentative.https.window.js28
-rw-r--r--tests/wpt/tests/fetch/fetch-later/policies/csp-blocked.tentative.https.window.js33
-rw-r--r--tests/wpt/tests/fetch/fetch-later/policies/csp-redirect-to-blocked.tentative.https.window.js33
-rw-r--r--tests/wpt/tests/fetch/fetch-later/resources/fetch-later.html14
-rw-r--r--tests/wpt/tests/fetch/fetch-later/resources/header-referrer-helper.js39
-rw-r--r--tests/wpt/tests/fetch/fetch-later/send-on-deactivate.tentative.https.window.js33
-rw-r--r--tests/wpt/tests/fetch/fetch-later/send-on-discard.tentative.https.window.js1
-rw-r--r--tests/wpt/tests/fledge/tentative/TODO13
-rw-r--r--tests/wpt/tests/fledge/tentative/auction-config.https.window.js31
-rw-r--r--tests/wpt/tests/fledge/tentative/currency.https.window.js124
-rw-r--r--tests/wpt/tests/fledge/tentative/join-leave-ad-interest-group.https.window.js11
-rw-r--r--tests/wpt/tests/fledge/tentative/network.https.window.js260
-rw-r--r--tests/wpt/tests/fledge/tentative/resources/bidding-logic.sub.py8
-rw-r--r--tests/wpt/tests/fledge/tentative/resources/fledge-util.sub.js65
-rw-r--r--tests/wpt/tests/fledge/tentative/resources/fledge_http_server_util.py11
-rw-r--r--tests/wpt/tests/fledge/tentative/resources/request-tracker.py27
-rw-r--r--tests/wpt/tests/fledge/tentative/resources/set-cookie.asis3
-rw-r--r--tests/wpt/tests/fledge/tentative/resources/trusted-bidding-signals.py3
-rw-r--r--tests/wpt/tests/fledge/tentative/resources/trusted-scoring-signals.py3
-rw-r--r--tests/wpt/tests/fullscreen/api/fullscreen-reordering.html2
-rw-r--r--tests/wpt/tests/generic-sensor/generic-sensor-iframe-tests.sub.js350
-rw-r--r--tests/wpt/tests/generic-sensor/generic-sensor-tests.js745
-rw-r--r--tests/wpt/tests/generic-sensor/resources/generic-sensor-helpers.js267
-rw-r--r--tests/wpt/tests/generic-sensor/resources/iframe_sensor_handler.html122
-rw-r--r--tests/wpt/tests/geolocation-sensor/GeolocationSensor-iframe-access.https.html5
-rw-r--r--tests/wpt/tests/geolocation-sensor/GeolocationSensor.https.html23
-rw-r--r--tests/wpt/tests/geolocation-sensor/resources/sensor-data.js17
-rw-r--r--tests/wpt/tests/gyroscope/Gyroscope-iframe-access.https.html5
-rw-r--r--tests/wpt/tests/gyroscope/Gyroscope.https.html22
-rw-r--r--tests/wpt/tests/gyroscope/resources/sensor-data.js23
-rw-r--r--tests/wpt/tests/hr-time/raf-coarsened-time.https.html33
-rw-r--r--tests/wpt/tests/hr-time/raf-coarsened-time.https.html.headers2
-rw-r--r--tests/wpt/tests/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/order-in-bfcache-restore.html70
-rw-r--r--tests/wpt/tests/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/order-in-new-document-navigation.html18
-rw-r--r--tests/wpt/tests/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/order-in-prerender-activation.html40
-rw-r--r--tests/wpt/tests/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/resources/order-in-prerender-activation-popup.html74
-rw-r--r--tests/wpt/tests/html/dom/elements/global-attributes/dir-auto-form-associated.window.js61
-rw-r--r--tests/wpt/tests/html/dom/elements/global-attributes/lang-attribute.window.js16
-rw-r--r--tests/wpt/tests/html/dom/elements/global-attributes/lang-xmllang-01-ref.html2
-rw-r--r--tests/wpt/tests/html/dom/elements/global-attributes/lang-xmllang-01.html2
-rw-r--r--tests/wpt/tests/html/dom/elements/global-attributes/lang-xyzzy.html2
-rw-r--r--tests/wpt/tests/html/infrastructure/urls/base-url/document-base-uri-synthetic-document.html34
-rw-r--r--tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-viewport-001.html14
-rw-r--r--tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-viewport-ref.html2
-rw-r--r--tests/wpt/tests/html/semantics/embedded-content/the-img-element/img-src-in-synthetic-document.html16
-rw-r--r--tests/wpt/tests/html/semantics/forms/attributes-common-to-form-controls/dirname-only-if-applies.html18
-rw-r--r--tests/wpt/tests/html/semantics/forms/the-input-element/input-disabled-fieldset-dynamic.html38
-rw-r--r--tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/dialog-cancel-events.html97
-rw-r--r--tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/dialog-cancel-preventDefault.html8
-rw-r--r--tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/dialog-canceling.html28
-rw-r--r--tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/focus-previous-iframe.tentative.html52
-rw-r--r--tests/wpt/tests/html/semantics/invokers/invokeelement-interface.tentative.html15
-rw-r--r--tests/wpt/tests/html/semantics/invokers/invokeevent-interface.tentative.html13
-rw-r--r--tests/wpt/tests/html/semantics/invokers/invoketarget-on-popover-behavior.tentative.html193
-rw-r--r--tests/wpt/tests/html/semantics/popovers/popover-close-request.html40
-rw-r--r--tests/wpt/tests/html/semantics/popovers/popover-top-layer-combinations.html1
-rw-r--r--tests/wpt/tests/html/semantics/popovers/popover-top-layer-interactions.html1
-rw-r--r--tests/wpt/tests/html/semantics/popovers/resources/popover-utils.js29
-rw-r--r--tests/wpt/tests/idle-detection/WEB_FEATURES.yml3
-rw-r--r--tests/wpt/tests/infrastructure/metadata/infrastructure/webdriver/tests/test_load_file.py.ini2
-rw-r--r--tests/wpt/tests/interfaces/invokers.tentative.idl2
-rw-r--r--tests/wpt/tests/jpegxl/3x3_jpeg_recompression-ref.html4
-rw-r--r--tests/wpt/tests/jpegxl/3x3_jpeg_recompression.html8
-rw-r--r--tests/wpt/tests/jpegxl/3x3_srgb_lossless-ref.html4
-rw-r--r--tests/wpt/tests/jpegxl/3x3_srgb_lossless.html8
-rw-r--r--tests/wpt/tests/jpegxl/3x3_srgb_lossy-ref.html (renamed from tests/wpt/tests/jpegxl/srgb-ref.html)2
-rw-r--r--tests/wpt/tests/jpegxl/3x3_srgb_lossy.html (renamed from tests/wpt/tests/jpegxl/srgb.html)5
-rw-r--r--tests/wpt/tests/jpegxl/3x3a_srgb_lossless-ref.html4
-rw-r--r--tests/wpt/tests/jpegxl/3x3a_srgb_lossless.html8
-rw-r--r--tests/wpt/tests/jpegxl/3x3a_srgb_lossy-ref.html4
-rw-r--r--tests/wpt/tests/jpegxl/3x3a_srgb_lossy.html8
-rw-r--r--tests/wpt/tests/jpegxl/resources/3x3.pngbin85 -> 0 bytes
-rw-r--r--tests/wpt/tests/jpegxl/resources/3x3_jpeg_recompression.jxlbin0 -> 422 bytes
-rw-r--r--tests/wpt/tests/jpegxl/resources/3x3_jpeg_recompression.pngbin0 -> 169 bytes
-rw-r--r--tests/wpt/tests/jpegxl/resources/3x3_srgb.jxlbin55 -> 0 bytes
-rw-r--r--tests/wpt/tests/jpegxl/resources/3x3_srgb_lossless.jxlbin0 -> 66 bytes
-rw-r--r--tests/wpt/tests/jpegxl/resources/3x3_srgb_lossless.pngbin0 -> 152 bytes
-rw-r--r--tests/wpt/tests/jpegxl/resources/3x3_srgb_lossy.jxlbin0 -> 200 bytes
-rw-r--r--tests/wpt/tests/jpegxl/resources/3x3_srgb_lossy.pngbin0 -> 156 bytes
-rw-r--r--tests/wpt/tests/jpegxl/resources/3x3a_srgb_lossless.jxlbin0 -> 66 bytes
-rw-r--r--tests/wpt/tests/jpegxl/resources/3x3a_srgb_lossless.pngbin0 -> 163 bytes
-rw-r--r--tests/wpt/tests/jpegxl/resources/3x3a_srgb_lossy.jxlbin0 -> 215 bytes
-rw-r--r--tests/wpt/tests/jpegxl/resources/3x3a_srgb_lossy.pngbin0 -> 167 bytes
-rwxr-xr-xtests/wpt/tests/jpegxl/resources/generate_resources.sh76
-rw-r--r--tests/wpt/tests/lint.ignore5
-rw-r--r--tests/wpt/tests/long-animation-frame/tentative/loaf-stream-source-location.html28
-rw-r--r--tests/wpt/tests/long-animation-frame/tentative/resources/stream-promise-generates-loaf.js12
-rw-r--r--tests/wpt/tests/magnetometer/Magnetometer-iframe-access.https.html7
-rw-r--r--tests/wpt/tests/magnetometer/Magnetometer.https.html29
-rw-r--r--tests/wpt/tests/magnetometer/resources/sensor-data.js21
-rw-r--r--tests/wpt/tests/mediacapture-extensions/MediaStreamTrack-video-stats.https.html8
-rw-r--r--tests/wpt/tests/orientation-sensor/AbsoluteOrientationSensor-iframe-access.https.html5
-rw-r--r--tests/wpt/tests/orientation-sensor/AbsoluteOrientationSensor.https.html14
-rw-r--r--tests/wpt/tests/orientation-sensor/RelativeOrientationSensor-iframe-access.https.html5
-rw-r--r--tests/wpt/tests/orientation-sensor/RelativeOrientationSensor.https.html14
-rw-r--r--tests/wpt/tests/orientation-sensor/orientation-sensor-tests.js115
-rw-r--r--tests/wpt/tests/orientation-sensor/resources/sensor-data.js26
-rw-r--r--tests/wpt/tests/pointerevents/pointerevent_after_target_removed.html8
-rw-r--r--tests/wpt/tests/requestidlecallback/callback-timeRemaining-cross-realm-method.html2
-rw-r--r--tests/wpt/tests/service-workers/service-worker/resources/scope1/redirect.py6
-rw-r--r--tests/wpt/tests/service-workers/service-worker/resources/scope2/worker_interception_redirect_webworker.py6
-rw-r--r--tests/wpt/tests/service-workers/service-worker/resources/subdir/worker_interception_redirect_webworker.py6
-rw-r--r--tests/wpt/tests/storage-access-api/helpers.js12
-rw-r--r--tests/wpt/tests/storage-access-api/requestStorageAccess-dedicated-worker.tentative.sub.https.window.js67
-rw-r--r--tests/wpt/tests/storage-access-api/resources/embedded_responder.js22
-rw-r--r--tests/wpt/tests/storage-access-api/resources/embedded_worker.js17
-rw-r--r--tests/wpt/tests/storage-access-api/resources/storage-access-beyond-cookies-iframe-iframe.html75
-rw-r--r--tests/wpt/tests/storage-access-api/resources/storage-access-beyond-cookies-iframe.sub.html62
-rw-r--r--tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.indexedDB.tentative.sub.https.window.js33
-rw-r--r--tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.localStorage.tentative.sub.https.window.js32
-rw-r--r--tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.locks.tentative.sub.https.window.js34
-rw-r--r--tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.sessionStorage.tentative.sub.https.window.js32
-rw-r--r--tests/wpt/tests/storage/estimate-indexeddb.https.any.js17
-rw-r--r--tests/wpt/tests/storage/storagemanager-estimate.https.any.js68
-rw-r--r--tests/wpt/tests/svg/extensibility/foreignObject/masked.html2
-rw-r--r--tests/wpt/tests/svg/pservers/scripted/pattern-transform-clear.svg17
-rwxr-xr-xtests/wpt/tests/tools/ci/ci_wptrunner_infrastructure.sh16
-rwxr-xr-xtests/wpt/tests/tools/ci/taskcluster-run.py17
-rw-r--r--tests/wpt/tests/tools/ci/tc/tasks/test.yml6
-rw-r--r--tests/wpt/tests/tools/ci/tc/tests/test_valid.py3
-rw-r--r--tests/wpt/tests/tools/runner/update_manifest.py6
-rw-r--r--tests/wpt/tests/tools/webdriver/webdriver/__init__.py7
-rw-r--r--tests/wpt/tests/tools/webdriver/webdriver/client.py141
-rw-r--r--tests/wpt/tests/tools/webdriver/webdriver/protocol.py24
-rw-r--r--tests/wpt/tests/tools/webdriver/webdriver/transport.py18
-rw-r--r--tests/wpt/tests/tools/wpt/utils.py15
-rw-r--r--tests/wpt/tests/tools/wptrunner/requirements.txt2
-rw-r--r--tests/wpt/tests/tools/wptrunner/wptrunner/browsers/content_shell.py36
-rw-r--r--tests/wpt/tests/tools/wptrunner/wptrunner/executors/base.py18
-rw-r--r--tests/wpt/tests/tools/wptrunner/wptrunner/stability.py8
-rw-r--r--tests/wpt/tests/tools/wptrunner/wptrunner/testrunner.py2
-rw-r--r--tests/wpt/tests/tools/wptrunner/wptrunner/tests/test_wptrunner.py79
-rw-r--r--tests/wpt/tests/tools/wptrunner/wptrunner/wptrunner.py36
-rw-r--r--tests/wpt/tests/wai-aria/role/invalid-roles.html4
-rw-r--r--tests/wpt/tests/wasm/jsapi/exception/basic.tentative.any.js9
-rw-r--r--tests/wpt/tests/wasm/jsapi/gc/casts.tentative.any.js332
-rw-r--r--tests/wpt/tests/wasm/jsapi/gc/exported-object.tentative.any.js190
-rw-r--r--tests/wpt/tests/wasm/jsapi/gc/i31.tentative.any.js98
-rw-r--r--tests/wpt/tests/wasm/jsapi/instanceTestFactory.js6
-rw-r--r--tests/wpt/tests/wasm/jsapi/module/exports.any.js6
-rw-r--r--tests/wpt/tests/wasm/jsapi/wasm-module-builder.js347
-rw-r--r--tests/wpt/tests/web-animations/animation-model/animation-types/scrollbar-interpolation.html91
-rw-r--r--tests/wpt/tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-default-value.html28
-rw-r--r--tests/wpt/tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-default-value.window.js12
-rw-r--r--tests/wpt/tests/webauthn/storecredential.https.html23
-rw-r--r--tests/wpt/tests/webcodecs/META.yml2
-rw-r--r--tests/wpt/tests/webcodecs/audio-decoder.https.any.js7
-rw-r--r--tests/wpt/tests/webcodecs/audio-encoder-config.https.any.js7
-rw-r--r--tests/wpt/tests/webcodecs/video-decoder.https.any.js9
-rw-r--r--tests/wpt/tests/webcodecs/video-encoder-config.https.any.js7
-rw-r--r--tests/wpt/tests/webdriver/tests/bidi/browsing_context/context_destroyed/__init__.py0
-rw-r--r--tests/wpt/tests/webdriver/tests/bidi/browsing_context/context_destroyed/context_destroyed.py248
-rw-r--r--tests/wpt/tests/webdriver/tests/bidi/browsing_context/user_prompt_opened/user_prompt_opened.py21
-rw-r--r--tests/wpt/tests/webdriver/tests/bidi/script/call_function/result_node.py151
-rw-r--r--tests/wpt/tests/webdriver/tests/bidi/script/classic_interop/node_shared_id.py4
-rw-r--r--tests/wpt/tests/webdriver/tests/bidi/script/evaluate/result_node.py145
-rw-r--r--tests/wpt/tests/webdriver/tests/classic/element_clear/clear.py8
-rw-r--r--tests/wpt/tests/webdriver/tests/classic/element_click/click.py8
-rw-r--r--tests/wpt/tests/webdriver/tests/classic/element_click/events.py2
-rw-r--r--tests/wpt/tests/webdriver/tests/classic/element_send_keys/send_keys.py8
-rw-r--r--tests/wpt/tests/webdriver/tests/classic/execute_async_script/arguments.py53
-rw-r--r--tests/wpt/tests/webdriver/tests/classic/execute_async_script/execute_async.py6
-rw-r--r--tests/wpt/tests/webdriver/tests/classic/execute_async_script/node.py10
-rw-r--r--tests/wpt/tests/webdriver/tests/classic/execute_async_script/window.py33
-rw-r--r--tests/wpt/tests/webdriver/tests/classic/execute_script/arguments.py50
-rw-r--r--tests/wpt/tests/webdriver/tests/classic/execute_script/execute.py2
-rw-r--r--tests/wpt/tests/webdriver/tests/classic/execute_script/json_serialize_windowproxy.py51
-rw-r--r--tests/wpt/tests/webdriver/tests/classic/execute_script/node.py12
-rw-r--r--tests/wpt/tests/webdriver/tests/classic/execute_script/window.py87
-rw-r--r--tests/wpt/tests/webdriver/tests/classic/find_element_from_shadow_root/find.py6
-rw-r--r--tests/wpt/tests/webdriver/tests/classic/find_elements_from_shadow_root/find.py6
-rw-r--r--tests/wpt/tests/webdriver/tests/classic/get_computed_label/get.py4
-rw-r--r--tests/wpt/tests/webdriver/tests/classic/get_computed_role/get.py4
-rw-r--r--tests/wpt/tests/webdriver/tests/classic/get_element_attribute/get.py4
-rw-r--r--tests/wpt/tests/webdriver/tests/classic/get_element_css_value/get.py4
-rw-r--r--tests/wpt/tests/webdriver/tests/classic/get_element_property/get.py10
-rw-r--r--tests/wpt/tests/webdriver/tests/classic/get_element_rect/get.py4
-rw-r--r--tests/wpt/tests/webdriver/tests/classic/get_element_shadow_root/get.py4
-rw-r--r--tests/wpt/tests/webdriver/tests/classic/get_element_tag_name/get.py4
-rw-r--r--tests/wpt/tests/webdriver/tests/classic/get_element_text/get.py4
-rw-r--r--tests/wpt/tests/webdriver/tests/classic/is_element_enabled/enabled.py4
-rw-r--r--tests/wpt/tests/webdriver/tests/classic/is_element_selected/selected.py4
-rw-r--r--tests/wpt/tests/webdriver/tests/classic/perform_actions/pointer_mouse.py18
-rw-r--r--tests/wpt/tests/webdriver/tests/classic/take_element_screenshot/screenshot.py4
-rw-r--r--tests/wpt/tests/webdriver/tests/support/asserts.py14
-rw-r--r--tests/wpt/tests/webtransport/echo-large-bidirectional-streams.https.any.js (renamed from tests/wpt/tests/webtransport/echo-large-bidirectional-streams.https.html)13
-rw-r--r--tests/wpt/tests/xhr/resources/auth1/auth.py5
-rw-r--r--tests/wpt/tests/xhr/resources/auth10/auth.py6
-rw-r--r--tests/wpt/tests/xhr/resources/auth11/auth.py5
-rw-r--r--tests/wpt/tests/xhr/resources/auth2/auth.py6
-rw-r--r--tests/wpt/tests/xhr/resources/auth2/corsenabled.py5
-rw-r--r--tests/wpt/tests/xhr/resources/auth3/auth.py5
-rw-r--r--tests/wpt/tests/xhr/resources/auth4/auth.py5
-rw-r--r--tests/wpt/tests/xhr/resources/auth7/corsenabled.py5
-rw-r--r--tests/wpt/tests/xhr/resources/auth8/corsenabled-no-authorize.py5
-rw-r--r--tests/wpt/tests/xhr/resources/auth9/auth.py5
438 files changed, 10664 insertions, 2514 deletions
diff --git a/tests/wpt/meta-legacy-layout/css/CSS2/linebox/inline-negative-margin-001.html.ini b/tests/wpt/meta-legacy-layout/css/CSS2/linebox/inline-negative-margin-001.html.ini
index a057f038339..5e3a96e5999 100644
--- a/tests/wpt/meta-legacy-layout/css/CSS2/linebox/inline-negative-margin-001.html.ini
+++ b/tests/wpt/meta-legacy-layout/css/CSS2/linebox/inline-negative-margin-001.html.ini
@@ -8,8 +8,5 @@
[[data-expected-height\] 3]
expected: FAIL
- [[data-expected-height\] 1]
- expected: FAIL
-
- [[data-expected-height\] 2]
+ [[data-expected-height\] 4]
expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/css/css-color/system-color-support.html.ini b/tests/wpt/meta-legacy-layout/css/css-color/system-color-support.html.ini
new file mode 100644
index 00000000000..28563ddd87a
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/css/css-color/system-color-support.html.ini
@@ -0,0 +1,57 @@
+[system-color-support.html]
+ [System color Canvas works]
+ expected: FAIL
+
+ [System color CanvasText works]
+ expected: FAIL
+
+ [System color LinkText works]
+ expected: FAIL
+
+ [System color VisitedText works]
+ expected: FAIL
+
+ [System color ActiveText works]
+ expected: FAIL
+
+ [System color ButtonFace works]
+ expected: FAIL
+
+ [System color ButtonText works]
+ expected: FAIL
+
+ [System color ButtonBorder works]
+ expected: FAIL
+
+ [System color Field works]
+ expected: FAIL
+
+ [System color FieldText works]
+ expected: FAIL
+
+ [System color Highlight works]
+ expected: FAIL
+
+ [System color HighlightText works]
+ expected: FAIL
+
+ [System color SelectedItem works]
+ expected: FAIL
+
+ [System color SelectedItemText works]
+ expected: FAIL
+
+ [System color Mark works]
+ expected: FAIL
+
+ [System color MarkText works]
+ expected: FAIL
+
+ [System color GrayText works]
+ expected: FAIL
+
+ [System color AccentColor works]
+ expected: FAIL
+
+ [System color AccentColorText works]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/css/css-color/t32-opacity-basic-0.6-a.xht.ini b/tests/wpt/meta-legacy-layout/css/css-color/t32-opacity-basic-0.6-a.xht.ini
deleted file mode 100644
index 4c252ef57be..00000000000
--- a/tests/wpt/meta-legacy-layout/css/css-color/t32-opacity-basic-0.6-a.xht.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[t32-opacity-basic-0.6-a.xht]
- expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/css/css-fonts/animations/font-palette-animation-not-specified-endpoints.html.ini b/tests/wpt/meta-legacy-layout/css/css-fonts/animations/font-palette-animation-not-specified-endpoints.html.ini
new file mode 100644
index 00000000000..48224fe6767
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/css/css-fonts/animations/font-palette-animation-not-specified-endpoints.html.ini
@@ -0,0 +1,7 @@
+[font-palette-animation-not-specified-endpoints.html]
+ expected: TIMEOUT
+ [Verify font-palette is animated when `from` keyframe is not specified]
+ expected: NOTRUN
+
+ [Verify font-palette is animated when `to` keyframe is not specified]
+ expected: NOTRUN
diff --git a/tests/wpt/meta-legacy-layout/css/css-images/parsing/gradient-interpolation-method-computed.html.ini b/tests/wpt/meta-legacy-layout/css/css-images/parsing/gradient-interpolation-method-computed.html.ini
index ac3cd32db81..9e15d59a455 100644
--- a/tests/wpt/meta-legacy-layout/css/css-images/parsing/gradient-interpolation-method-computed.html.ini
+++ b/tests/wpt/meta-legacy-layout/css/css-images/parsing/gradient-interpolation-method-computed.html.ini
@@ -815,12 +815,6 @@
[Property background-image value 'linear-gradient(in oklch decreasing hue to right bottom, color(srgb 1 0 0), blue)']
expected: FAIL
- [Property background-image value 'radial-gradient(ellipse 50% 40em, red, blue)']
- expected: FAIL
-
- [Property background-image value 'radial-gradient(at right center, red, blue)']
- expected: FAIL
-
[Property background-image value 'radial-gradient(50px, color(srgb 1 0 0), blue)']
expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/css/css-text/inheritance.html.ini b/tests/wpt/meta-legacy-layout/css/css-text/inheritance.html.ini
index 415926291db..5eb631e5b9b 100644
--- a/tests/wpt/meta-legacy-layout/css/css-text/inheritance.html.ini
+++ b/tests/wpt/meta-legacy-layout/css/css-text/inheritance.html.ini
@@ -46,3 +46,15 @@
[Property white-space-collapse inherits]
expected: FAIL
+
+ [Property text-wrap-mode has initial value wrap]
+ expected: FAIL
+
+ [Property text-wrap-mode inherits]
+ expected: FAIL
+
+ [Property text-wrap-style has initial value auto]
+ expected: FAIL
+
+ [Property text-wrap-style inherits]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/css/css-text/parsing/text-wrap-computed.html.ini b/tests/wpt/meta-legacy-layout/css/css-text/parsing/text-wrap-computed.html.ini
new file mode 100644
index 00000000000..dbe3756bbab
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/css/css-text/parsing/text-wrap-computed.html.ini
@@ -0,0 +1,66 @@
+[text-wrap-computed.html]
+ [Property text-wrap value 'wrap']
+ expected: FAIL
+
+ [Property text-wrap value 'nowrap']
+ expected: FAIL
+
+ [Property text-wrap value 'auto']
+ expected: FAIL
+
+ [Property text-wrap value 'balance']
+ expected: FAIL
+
+ [Property text-wrap value 'stable']
+ expected: FAIL
+
+ [Property text-wrap value 'pretty']
+ expected: FAIL
+
+ [Property text-wrap value 'wrap auto']
+ expected: FAIL
+
+ [Property text-wrap value 'wrap balance']
+ expected: FAIL
+
+ [Property text-wrap value 'wrap pretty']
+ expected: FAIL
+
+ [Property text-wrap value 'wrap stable']
+ expected: FAIL
+
+ [Property text-wrap value 'auto wrap']
+ expected: FAIL
+
+ [Property text-wrap value 'balance wrap']
+ expected: FAIL
+
+ [Property text-wrap value 'pretty wrap']
+ expected: FAIL
+
+ [Property text-wrap value 'stable wrap']
+ expected: FAIL
+
+ [Property text-wrap value 'nowrap auto']
+ expected: FAIL
+
+ [Property text-wrap value 'nowrap balance']
+ expected: FAIL
+
+ [Property text-wrap value 'nowrap pretty']
+ expected: FAIL
+
+ [Property text-wrap value 'nowrap stable']
+ expected: FAIL
+
+ [Property text-wrap value 'auto nowrap']
+ expected: FAIL
+
+ [Property text-wrap value 'balance nowrap']
+ expected: FAIL
+
+ [Property text-wrap value 'pretty nowrap']
+ expected: FAIL
+
+ [Property text-wrap value 'stable nowrap']
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/css/css-text/parsing/text-wrap-mode-computed.html.ini b/tests/wpt/meta-legacy-layout/css/css-text/parsing/text-wrap-mode-computed.html.ini
new file mode 100644
index 00000000000..f9739ca0b28
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/css/css-text/parsing/text-wrap-mode-computed.html.ini
@@ -0,0 +1,6 @@
+[text-wrap-mode-computed.html]
+ [Property text-wrap-mode value 'wrap']
+ expected: FAIL
+
+ [Property text-wrap-mode value 'nowrap']
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/css/css-text/parsing/text-wrap-mode-valid.html.ini b/tests/wpt/meta-legacy-layout/css/css-text/parsing/text-wrap-mode-valid.html.ini
new file mode 100644
index 00000000000..76dc7a87b4e
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/css/css-text/parsing/text-wrap-mode-valid.html.ini
@@ -0,0 +1,21 @@
+[text-wrap-mode-valid.html]
+ [e.style['text-wrap-mode'\] = "wrap" should set the property value]
+ expected: FAIL
+
+ [e.style['text-wrap-mode'\] = "nowrap" should set the property value]
+ expected: FAIL
+
+ [e.style['text-wrap-mode'\] = "initial" should set the property value]
+ expected: FAIL
+
+ [e.style['text-wrap-mode'\] = "inherit" should set the property value]
+ expected: FAIL
+
+ [e.style['text-wrap-mode'\] = "unset" should set the property value]
+ expected: FAIL
+
+ [e.style['text-wrap-mode'\] = "revert" should set the property value]
+ expected: FAIL
+
+ [e.style['text-wrap-mode'\] = "revert-layer" should set the property value]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/css/css-text/parsing/text-wrap-style-computed.html.ini b/tests/wpt/meta-legacy-layout/css/css-text/parsing/text-wrap-style-computed.html.ini
new file mode 100644
index 00000000000..8be1df9f7ff
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/css/css-text/parsing/text-wrap-style-computed.html.ini
@@ -0,0 +1,12 @@
+[text-wrap-style-computed.html]
+ [Property text-wrap-style value 'auto']
+ expected: FAIL
+
+ [Property text-wrap-style value 'balance']
+ expected: FAIL
+
+ [Property text-wrap-style value 'pretty']
+ expected: FAIL
+
+ [Property text-wrap-style value 'stable']
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/css/css-text/parsing/text-wrap-style-valid.html.ini b/tests/wpt/meta-legacy-layout/css/css-text/parsing/text-wrap-style-valid.html.ini
new file mode 100644
index 00000000000..fd637df85db
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/css/css-text/parsing/text-wrap-style-valid.html.ini
@@ -0,0 +1,27 @@
+[text-wrap-style-valid.html]
+ [e.style['text-wrap-style'\] = "auto" should set the property value]
+ expected: FAIL
+
+ [e.style['text-wrap-style'\] = "balance" should set the property value]
+ expected: FAIL
+
+ [e.style['text-wrap-style'\] = "pretty" should set the property value]
+ expected: FAIL
+
+ [e.style['text-wrap-style'\] = "stable" should set the property value]
+ expected: FAIL
+
+ [e.style['text-wrap-style'\] = "initial" should set the property value]
+ expected: FAIL
+
+ [e.style['text-wrap-style'\] = "inherit" should set the property value]
+ expected: FAIL
+
+ [e.style['text-wrap-style'\] = "unset" should set the property value]
+ expected: FAIL
+
+ [e.style['text-wrap-style'\] = "revert" should set the property value]
+ expected: FAIL
+
+ [e.style['text-wrap-style'\] = "revert-layer" should set the property value]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/css/css-values/round-mod-rem-computed.html.ini b/tests/wpt/meta-legacy-layout/css/css-values/round-mod-rem-computed.html.ini
index dc53d195dec..f4e2b78dd6f 100644
--- a/tests/wpt/meta-legacy-layout/css/css-values/round-mod-rem-computed.html.ini
+++ b/tests/wpt/meta-legacy-layout/css/css-values/round-mod-rem-computed.html.ini
@@ -706,3 +706,12 @@
[mod(4, -Infinity) should be used-value-equivalent to calc(NaN)]
expected: FAIL
+
+ [round(1px + 0%, 1px) should be used-value-equivalent to 1px]
+ expected: FAIL
+
+ [mod(3px + 0%, 2px) should be used-value-equivalent to 1px]
+ expected: FAIL
+
+ [rem(3px + 0%, 2px) should be used-value-equivalent to 1px]
+ 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 a3e30250229..977ef8f774c 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
@@ -1,6 +1,3 @@
[scroll-behavior-smooth-navigation.html]
[Instant scrolling while doing history navigation.]
expected: FAIL
-
- [Smooth scrolling while doing history navigation.]
- expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/fetch/fetch-later/headers/header-referrer-no-referrer-when-downgrade.tentative.https.html.ini b/tests/wpt/meta-legacy-layout/fetch/fetch-later/headers/header-referrer-no-referrer-when-downgrade.tentative.https.html.ini
new file mode 100644
index 00000000000..3274b486b81
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/fetch/fetch-later/headers/header-referrer-no-referrer-when-downgrade.tentative.https.html.ini
@@ -0,0 +1,3 @@
+[header-referrer-no-referrer-when-downgrade.tentative.https.html]
+ [Test referer header https://web-platform.test:8443]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/fetch/fetch-later/headers/header-referrer-no-referrer.tentative.https.html.ini b/tests/wpt/meta-legacy-layout/fetch/fetch-later/headers/header-referrer-no-referrer.tentative.https.html.ini
new file mode 100644
index 00000000000..f9977a9008e
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/fetch/fetch-later/headers/header-referrer-no-referrer.tentative.https.html.ini
@@ -0,0 +1,3 @@
+[header-referrer-no-referrer.tentative.https.html]
+ [Test referer header ]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/fetch/fetch-later/headers/header-referrer-origin-when-cross-origin.tentative.https.html.ini b/tests/wpt/meta-legacy-layout/fetch/fetch-later/headers/header-referrer-origin-when-cross-origin.tentative.https.html.ini
new file mode 100644
index 00000000000..38a364e11ea
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/fetch/fetch-later/headers/header-referrer-origin-when-cross-origin.tentative.https.html.ini
@@ -0,0 +1,6 @@
+[header-referrer-origin-when-cross-origin.tentative.https.html]
+ [Test referer header https://web-platform.test:8443]
+ expected: FAIL
+
+ [Test referer header https://www1.web-platform.test:8443]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/fetch/fetch-later/headers/header-referrer-origin.tentative.https.html.ini b/tests/wpt/meta-legacy-layout/fetch/fetch-later/headers/header-referrer-origin.tentative.https.html.ini
new file mode 100644
index 00000000000..06fe8584f00
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/fetch/fetch-later/headers/header-referrer-origin.tentative.https.html.ini
@@ -0,0 +1,3 @@
+[header-referrer-origin.tentative.https.html]
+ [Test referer header https://www1.web-platform.test:8443]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/fetch/fetch-later/headers/header-referrer-same-origin.tentative.https.html.ini b/tests/wpt/meta-legacy-layout/fetch/fetch-later/headers/header-referrer-same-origin.tentative.https.html.ini
new file mode 100644
index 00000000000..ea9ac6e351c
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/fetch/fetch-later/headers/header-referrer-same-origin.tentative.https.html.ini
@@ -0,0 +1,6 @@
+[header-referrer-same-origin.tentative.https.html]
+ [Test referer header ]
+ expected: FAIL
+
+ [Test referer header https://www1.web-platform.test:8443]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/fetch/fetch-later/headers/header-referrer-strict-origin-when-cross-origin.tentative.https.html.ini b/tests/wpt/meta-legacy-layout/fetch/fetch-later/headers/header-referrer-strict-origin-when-cross-origin.tentative.https.html.ini
new file mode 100644
index 00000000000..0bf2b43e93f
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/fetch/fetch-later/headers/header-referrer-strict-origin-when-cross-origin.tentative.https.html.ini
@@ -0,0 +1,3 @@
+[header-referrer-strict-origin-when-cross-origin.tentative.https.html]
+ [Test referer header https://www1.web-platform.test:8443]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/fetch/fetch-later/headers/header-referrer-strict-origin.tentative.https.html.ini b/tests/wpt/meta-legacy-layout/fetch/fetch-later/headers/header-referrer-strict-origin.tentative.https.html.ini
new file mode 100644
index 00000000000..9c67727f1b1
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/fetch/fetch-later/headers/header-referrer-strict-origin.tentative.https.html.ini
@@ -0,0 +1,3 @@
+[header-referrer-strict-origin.tentative.https.html]
+ [Test referer header https://web-platform.test:8443]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/fetch/fetch-later/headers/header-referrer-unsafe-url.tentative.https.html.ini b/tests/wpt/meta-legacy-layout/fetch/fetch-later/headers/header-referrer-unsafe-url.tentative.https.html.ini
new file mode 100644
index 00000000000..979914e33f8
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/fetch/fetch-later/headers/header-referrer-unsafe-url.tentative.https.html.ini
@@ -0,0 +1,3 @@
+[header-referrer-unsafe-url.tentative.https.html]
+ [Test referer header https://web-platform.test:8443]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/fetch/fetch-later/iframe.tentative.https.window.js.ini b/tests/wpt/meta-legacy-layout/fetch/fetch-later/iframe.tentative.https.window.js.ini
new file mode 100644
index 00000000000..b3d4cb1d9f1
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/fetch/fetch-later/iframe.tentative.https.window.js.ini
@@ -0,0 +1,2 @@
+[iframe.tentative.https.window.html]
+ expected: ERROR
diff --git a/tests/wpt/meta-legacy-layout/fetch/fetch-later/new-window.tentative.https.window.js.ini b/tests/wpt/meta-legacy-layout/fetch/fetch-later/new-window.tentative.https.window.js.ini
new file mode 100644
index 00000000000..1f36e0e5b51
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/fetch/fetch-later/new-window.tentative.https.window.js.ini
@@ -0,0 +1,2 @@
+[new-window.tentative.https.window.html]
+ expected: ERROR
diff --git a/tests/wpt/meta-legacy-layout/fetch/fetch-later/policies/csp-allowed.tentative.https.window.js.ini b/tests/wpt/meta-legacy-layout/fetch/fetch-later/policies/csp-allowed.tentative.https.window.js.ini
new file mode 100644
index 00000000000..357487889e9
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/fetch/fetch-later/policies/csp-allowed.tentative.https.window.js.ini
@@ -0,0 +1,2 @@
+[csp-allowed.tentative.https.window.html]
+ expected: ERROR
diff --git a/tests/wpt/meta-legacy-layout/fetch/fetch-later/policies/csp-blocked.tentative.https.window.js.ini b/tests/wpt/meta-legacy-layout/fetch/fetch-later/policies/csp-blocked.tentative.https.window.js.ini
new file mode 100644
index 00000000000..f6d883b2101
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/fetch/fetch-later/policies/csp-blocked.tentative.https.window.js.ini
@@ -0,0 +1,2 @@
+[csp-blocked.tentative.https.window.html]
+ expected: ERROR
diff --git a/tests/wpt/meta-legacy-layout/fetch/fetch-later/policies/csp-redirect-to-blocked.tentative.https.window.js.ini b/tests/wpt/meta-legacy-layout/fetch/fetch-later/policies/csp-redirect-to-blocked.tentative.https.window.js.ini
new file mode 100644
index 00000000000..23cc9814012
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/fetch/fetch-later/policies/csp-redirect-to-blocked.tentative.https.window.js.ini
@@ -0,0 +1,2 @@
+[csp-redirect-to-blocked.tentative.https.window.html]
+ expected: ERROR
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 f0cfa5a9e3f..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,12 +146,3 @@
[list-style-image sec-fetch-site - HTTPS downgrade-upgrade]
expected: FAIL
-
- [background-image sec-fetch-site - HTTPS downgrade (header not sent)]
- expected: TIMEOUT
-
- [border-image sec-fetch-site - HTTPS downgrade (header not sent)]
- expected: FAIL
-
- [background-image sec-fetch-mode - Not sent to non-trustworthy same-origin destination]
- expected: TIMEOUT
diff --git a/tests/wpt/meta-legacy-layout/hr-time/raf-coarsened-time.https.html.ini b/tests/wpt/meta-legacy-layout/hr-time/raf-coarsened-time.https.html.ini
new file mode 100644
index 00000000000..b4991611fcf
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/hr-time/raf-coarsened-time.https.html.ini
@@ -0,0 +1,2 @@
+[raf-coarsened-time.https.html]
+ expected: ERROR
diff --git a/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/order-in-bfcache-restore.html.ini b/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/order-in-bfcache-restore.html.ini
new file mode 100644
index 00000000000..46f10274f9f
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/order-in-bfcache-restore.html.ini
@@ -0,0 +1,4 @@
+[order-in-bfcache-restore.html]
+ expected: TIMEOUT
+ [pagereveal event fires and in correct order on restoration from BFCache]
+ expected: TIMEOUT
diff --git a/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/order-in-new-document-navigation.html.ini b/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/order-in-new-document-navigation.html.ini
new file mode 100644
index 00000000000..721a89932a1
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/order-in-new-document-navigation.html.ini
@@ -0,0 +1,3 @@
+[order-in-new-document-navigation.html]
+ [pagereveal event fires and in correct order on new-document navigation]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/order-in-prerender-activation.html.ini b/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/order-in-prerender-activation.html.ini
new file mode 100644
index 00000000000..b6c1d6dbec6
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/order-in-prerender-activation.html.ini
@@ -0,0 +1,2 @@
+[order-in-prerender-activation.html]
+ expected: ERROR
diff --git a/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/iframe-src-aboutblank-navigate-immediately.html.ini b/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/iframe-src-aboutblank-navigate-immediately.html.ini
index 1bca09f21d6..c5fc1407992 100644
--- a/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/iframe-src-aboutblank-navigate-immediately.html.ini
+++ b/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/iframe-src-aboutblank-navigate-immediately.html.ini
@@ -1,4 +1,5 @@
[iframe-src-aboutblank-navigate-immediately.html]
+ expected: TIMEOUT
[Navigating to a different document with window.open]
expected: FAIL
@@ -6,4 +7,4 @@
expected: FAIL
[Navigating to a different document with form submission]
- expected: FAIL
+ expected: TIMEOUT
diff --git a/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/load-pageshow-events-iframe-contentWindow.html.ini b/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/load-pageshow-events-iframe-contentWindow.html.ini
index 51fd557bd7f..d19311abec9 100644
--- a/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/load-pageshow-events-iframe-contentWindow.html.ini
+++ b/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/load-pageshow-events-iframe-contentWindow.html.ini
@@ -7,3 +7,9 @@
[load & pageshow events do not fire on contentWindow of <iframe> element created with src='about:blank#foo']
expected: FAIL
+
+ [load & pageshow events do not fire on contentWindow of <iframe> element created with src='']
+ expected: FAIL
+
+ [load & pageshow events do not fire on contentWindow of <iframe> element created with src='about:blank']
+ 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
new file mode 100644
index 00000000000..4ecd6d9f753
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-cross-origin.sub.window.js.ini
@@ -0,0 +1,3 @@
+[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/canvas/element/manual/drawing-text-to-the-canvas/canvas.2d.disconnected-font-size-math.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/element/manual/drawing-text-to-the-canvas/canvas.2d.disconnected-font-size-math.html.ini
new file mode 100644
index 00000000000..addd810a23d
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/html/canvas/element/manual/drawing-text-to-the-canvas/canvas.2d.disconnected-font-size-math.html.ini
@@ -0,0 +1,2 @@
+[canvas.2d.disconnected-font-size-math.html]
+ expected: CRASH
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 17247137cb1..5cdcce07c65 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: CRASH
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/dom/elements/global-attributes/dir-auto-form-associated.window.js.ini b/tests/wpt/meta-legacy-layout/html/dom/elements/global-attributes/dir-auto-form-associated.window.js.ini
new file mode 100644
index 00000000000..9b19b29d20e
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/html/dom/elements/global-attributes/dir-auto-form-associated.window.js.ini
@@ -0,0 +1,66 @@
+[dir-auto-form-associated.window.html]
+ [<input dir=auto type=hidden> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=text> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=search> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=tel> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=url> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=email> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=password> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=submit> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=reset> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=button> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=date> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=month> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=week> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=time> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=datetime-local> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=number> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=range> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=color> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=checkbox> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=radio> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=image> directionality]
+ expected: FAIL
+
+ [<textarea dir=auto> directionality]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/dom/elements/global-attributes/lang-attribute.window.js.ini b/tests/wpt/meta-legacy-layout/html/dom/elements/global-attributes/lang-attribute.window.js.ini
new file mode 100644
index 00000000000..9a9467a8817
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/html/dom/elements/global-attributes/lang-attribute.window.js.ini
@@ -0,0 +1,3 @@
+[lang-attribute.window.html]
+ [unnamespaced lang attribute only works on elements in the HTML namespace]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-1.html.ini b/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-1.html.ini
index 25d9964f057..e5994e21efc 100644
--- a/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-1.html.ini
+++ b/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-1.html.ini
@@ -1,4 +1,5 @@
[iframe_sandbox_popups_escaping-1.html]
type: testharness
+ expected: CRASH
[Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used]
expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-2.html.ini b/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-2.html.ini
index 26704422bbe..841bafc6eca 100644
--- a/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-2.html.ini
+++ b/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-2.html.ini
@@ -1,4 +1,3 @@
[iframe_sandbox_popups_escaping-2.html]
- expected: TIMEOUT
[Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used]
- expected: TIMEOUT
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-3.html.ini b/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-3.html.ini
index fe55ddae3f1..eacbe5794ea 100644
--- a/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-3.html.ini
+++ b/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-3.html.ini
@@ -1,4 +1,5 @@
[iframe_sandbox_popups_escaping-3.html]
type: testharness
+ expected: TIMEOUT
[Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used]
- expected: FAIL
+ expected: TIMEOUT
diff --git a/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html.ini b/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html.ini
index 6f7461b9472..f9138fb999a 100644
--- a/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html.ini
+++ b/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html.ini
@@ -1,4 +1,5 @@
[iframe_sandbox_popups_nonescaping-1.html]
type: testharness
+ expected: TIMEOUT
[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/embedded-content/the-img-element/non-active-document.html.ini b/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-img-element/non-active-document.html.ini
index 47b45e65a1c..3cdeb8ebcbc 100644
--- a/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-img-element/non-active-document.html.ini
+++ b/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-img-element/non-active-document.html.ini
@@ -1,9 +1,3 @@
[non-active-document.html]
[DOMParser]
expected: FAIL
-
- [createHTMLDocument]
- expected: FAIL
-
- [<template>]
- expected: FAIL
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 d2d031e78b0..56543701e05 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
@@ -178,3 +178,9 @@
[text/plain: Basic test (formdata event)]
expected: FAIL
+
+ [text/plain: 0x00 in name (normal form)]
+ expected: FAIL
+
+ [text/plain: double quote in name (formdata event)]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/semantics/forms/historical.html.ini b/tests/wpt/meta-legacy-layout/html/semantics/forms/historical.html.ini
deleted file mode 100644
index 5d8289307cc..00000000000
--- a/tests/wpt/meta-legacy-layout/html/semantics/forms/historical.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[historical.html]
- [<input name=isindex> should not be supported]
- expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/semantics/invokers/invokeelement-interface.tentative.html.ini b/tests/wpt/meta-legacy-layout/html/semantics/invokers/invokeelement-interface.tentative.html.ini
index e1534b63047..e8781936e24 100644
--- a/tests/wpt/meta-legacy-layout/html/semantics/invokers/invokeelement-interface.tentative.html.ini
+++ b/tests/wpt/meta-legacy-layout/html/semantics/invokers/invokeelement-interface.tentative.html.ini
@@ -31,3 +31,6 @@
[invokeAction reflects tostring value 2]
expected: FAIL
+
+ [invokeAction reflects same casing]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_noopener.html.ini b/tests/wpt/meta-legacy-layout/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_noopener.html.ini
index cc18f512574..071b4378add 100644
--- a/tests/wpt/meta-legacy-layout/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_noopener.html.ini
+++ b/tests/wpt/meta-legacy-layout/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_noopener.html.ini
@@ -11,6 +11,3 @@
[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-legacy-layout/html/semantics/scripting-1/the-script-element/defer-script/async-script.html.ini b/tests/wpt/meta-legacy-layout/html/semantics/scripting-1/the-script-element/defer-script/async-script.html.ini
deleted file mode 100644
index 6339abba6d9..00000000000
--- a/tests/wpt/meta-legacy-layout/html/semantics/scripting-1/the-script-element/defer-script/async-script.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[async-script.html?reload]
- expected: ERROR
-
-[async-script.html?default]
diff --git a/tests/wpt/meta-legacy-layout/html/syntax/parsing/DOMContentLoaded-defer.html.ini b/tests/wpt/meta-legacy-layout/html/syntax/parsing/DOMContentLoaded-defer.html.ini
deleted file mode 100644
index b8bdf33cb65..00000000000
--- a/tests/wpt/meta-legacy-layout/html/syntax/parsing/DOMContentLoaded-defer.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[DOMContentLoaded-defer.html]
- [The end: DOMContentLoaded and defer scripts]
- expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-job-queue/promise-job-entry-different-function-realm.html.ini b/tests/wpt/meta-legacy-layout/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-job-queue/promise-job-entry-different-function-realm.html.ini
index 7237f5792de..dbe1def99e3 100644
--- a/tests/wpt/meta-legacy-layout/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-job-queue/promise-job-entry-different-function-realm.html.ini
+++ b/tests/wpt/meta-legacy-layout/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-job-queue/promise-job-entry-different-function-realm.html.ini
@@ -1,10 +1,9 @@
[promise-job-entry-different-function-realm.html]
- expected: TIMEOUT
[Fulfillment handler on fulfilled promise]
expected: FAIL
[Rejection handler on pending-then-rejected promise]
- expected: TIMEOUT
+ expected: FAIL
[Thenable resolution]
expected: FAIL
@@ -13,4 +12,4 @@
expected: FAIL
[Fulfillment handler on pending-then-fulfilled promise]
- expected: TIMEOUT
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/webappapis/scripting/processing-model-2/unhandled-promise-rejections/promise-rejection-events.html.ini b/tests/wpt/meta-legacy-layout/html/webappapis/scripting/processing-model-2/unhandled-promise-rejections/promise-rejection-events.html.ini
index 4a48dd15a9d..1d71471b73c 100644
--- a/tests/wpt/meta-legacy-layout/html/webappapis/scripting/processing-model-2/unhandled-promise-rejections/promise-rejection-events.html.ini
+++ b/tests/wpt/meta-legacy-layout/html/webappapis/scripting/processing-model-2/unhandled-promise-rejections/promise-rejection-events.html.ini
@@ -1,6 +1,7 @@
[promise-rejection-events.html]
+ expected: TIMEOUT
[delayed handling: delaying handling rejected promise created from createImageBitmap will cause both events to fire]
- expected: FAIL
+ expected: TIMEOUT
[unhandledrejection: from createImageBitmap which is UA triggered]
expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/wasm/jsapi/gc/casts.tentative.any.js.ini b/tests/wpt/meta-legacy-layout/wasm/jsapi/gc/casts.tentative.any.js.ini
new file mode 100644
index 00000000000..0b499ced6d7
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/wasm/jsapi/gc/casts.tentative.any.js.ini
@@ -0,0 +1,5 @@
+[casts.tentative.any.worker.html]
+ expected: ERROR
+
+[casts.tentative.any.html]
+ expected: ERROR
diff --git a/tests/wpt/meta-legacy-layout/wasm/jsapi/gc/exported-object.tentative.any.js.ini b/tests/wpt/meta-legacy-layout/wasm/jsapi/gc/exported-object.tentative.any.js.ini
new file mode 100644
index 00000000000..59dd05d2b08
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/wasm/jsapi/gc/exported-object.tentative.any.js.ini
@@ -0,0 +1,5 @@
+[exported-object.tentative.any.worker.html]
+ expected: ERROR
+
+[exported-object.tentative.any.html]
+ expected: ERROR
diff --git a/tests/wpt/meta-legacy-layout/wasm/jsapi/gc/i31.tentative.any.js.ini b/tests/wpt/meta-legacy-layout/wasm/jsapi/gc/i31.tentative.any.js.ini
new file mode 100644
index 00000000000..485ae1ecd1c
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/wasm/jsapi/gc/i31.tentative.any.js.ini
@@ -0,0 +1,5 @@
+[i31.tentative.any.worker.html]
+ expected: ERROR
+
+[i31.tentative.any.html]
+ expected: ERROR
diff --git a/tests/wpt/meta-legacy-layout/webmessaging/with-ports/018.html.ini b/tests/wpt/meta-legacy-layout/webmessaging/with-ports/018.html.ini
new file mode 100644
index 00000000000..b7b36c1d3a4
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/webmessaging/with-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/webmessaging/without-ports/017.html.ini b/tests/wpt/meta-legacy-layout/webmessaging/without-ports/017.html.ini
deleted file mode 100644
index c7946fc91b4..00000000000
--- a/tests/wpt/meta-legacy-layout/webmessaging/without-ports/017.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[017.html]
- expected: TIMEOUT
- [origin of the script that invoked the method, about:blank]
- expected: TIMEOUT
diff --git a/tests/wpt/meta-legacy-layout/webstorage/localstorage-about-blank-3P-iframe-opens-3P-window.partitioned.tentative.html.ini b/tests/wpt/meta-legacy-layout/webstorage/localstorage-about-blank-3P-iframe-opens-3P-window.partitioned.tentative.html.ini
deleted file mode 100644
index aa6c9e5b826..00000000000
--- a/tests/wpt/meta-legacy-layout/webstorage/localstorage-about-blank-3P-iframe-opens-3P-window.partitioned.tentative.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[localstorage-about-blank-3P-iframe-opens-3P-window.partitioned.tentative.html]
- expected: TIMEOUT
- [StorageKey: test 3P about:blank window opened from a 3P iframe]
- expected: TIMEOUT
diff --git a/tests/wpt/meta/MANIFEST.json b/tests/wpt/meta/MANIFEST.json
index 7495768a479..452da213d24 100644
--- a/tests/wpt/meta/MANIFEST.json
+++ b/tests/wpt/meta/MANIFEST.json
@@ -2349,13 +2349,6 @@
]
]
},
- "dynamic-counters-crash.html": [
- "41e98ce003750d702e2a0fa0fc144e83532b9060",
- [
- null,
- {}
- ]
- ],
"list-item-counter-crash.html": [
"fc8a38c628026dc190d81e27150d8ebabb130ae2",
[
@@ -3545,6 +3538,15 @@
]
]
},
+ "css-scoping": {
+ "chrome-1492368-crash.html": [
+ "04d48ef21532405548b80e23c482e848b3fc1ef6",
+ [
+ null,
+ {}
+ ]
+ ]
+ },
"css-scroll-anchoring": {
"fullscreen-crash.html": [
"545f2919b55ffe31f942e547d5299c00ee89d715",
@@ -3911,6 +3913,13 @@
{}
]
],
+ "text-indent-each-line-crash.html": [
+ "fb63175cf179871e76b8d30e3016401626725769",
+ [
+ null,
+ {}
+ ]
+ ],
"text-wrap-balance-float-crash.html": [
"a4767b07615925aebd31343e81b772c8712e8756",
[
@@ -4510,6 +4519,13 @@
{}
]
],
+ "insert-dir-rule-crash.html": [
+ "6cffa0c62a522f201f9dd531bc3774df46b7d394",
+ [
+ null,
+ {}
+ ]
+ ],
"insert-dir-rule-in-iframe-crash.html": [
"4c9d7530dc359719166e16dbd93ed0088c3ca7d5",
[
@@ -153971,7 +153987,7 @@
]
],
"lch-009.html": [
- "472e7c138f720f995506100c04f661143f4136cb",
+ "375fd08de5833cc0ef0619e762c98b2bc289b13c",
[
null,
[
@@ -153984,7 +154000,7 @@
]
],
"lch-010.html": [
- "527e9cc7aff679a16da65f2ea10965b896cd99e6",
+ "965e05ff5dc0a16b169ba5f22d261c180f719a74",
[
null,
[
@@ -154309,7 +154325,7 @@
]
],
"oklch-009.html": [
- "5a4924a7e282885a6238011ec90492af49421c1a",
+ "1882c476c1c8678dd8e0e7d443735c25d63f02ca",
[
null,
[
@@ -154322,7 +154338,7 @@
]
],
"oklch-010.html": [
- "091b760bea29bed450a21c9620eec2b0823bdc84",
+ "b5f9ac206b45eb031ac0330fef22923a319cf472",
[
null,
[
@@ -155180,12 +155196,12 @@
]
],
"t32-opacity-basic-0.6-a.xht": [
- "3687d5392e30ed929fa3ab00d851b7e9754ab8ff",
+ "541964f8d6131e3b47b0edf6ea867cd331603a5d",
[
null,
[
[
- "/css/css-color/t32-opacity-basic-0.6-a-ref.html",
+ "/css/css-color/t32-opacity-basic-0.6-a-ref.xht",
"=="
]
],
@@ -155469,12 +155485,12 @@
]
],
"t422-rgba-a0.6-a.xht": [
- "2274eb3c3127c76862ade6b974ca55ccea47bab4",
+ "a710a0b62513969e8a7479a81fef70d09d87d956",
[
null,
[
[
- "/css/css-color/t32-opacity-basic-0.6-a-ref.html",
+ "/css/css-color/t422-rgba-a0.6-a-ref.xht",
"=="
]
],
@@ -155872,12 +155888,12 @@
]
],
"t425-hsla-basic-a.xht": [
- "3645a9acedf0e13af91ceff4733e1edd54adab16",
+ "435041b5fa9b0f003adb893e96550765f7effc3c",
[
null,
[
[
- "/css/css-color/t425-hsla-basic-a-ref.html",
+ "/css/css-color/t425-hsla-basic-a-ref.xht",
"=="
]
],
@@ -156145,7 +156161,7 @@
]
],
"xyz-d50-003.html": [
- "036bcb6c148fabb6b859a236caff248175b86ad8",
+ "7630115187454cab97615eec49e59a6e446da285",
[
null,
[
@@ -156158,7 +156174,7 @@
]
],
"xyz-d50-004.html": [
- "cc178590eaeeed69070cc48935ad73d43a89ae97",
+ "f4aa9a0a1d5730e5180fc06e6a21a9bb51908066",
[
null,
[
@@ -195311,7 +195327,7 @@
]
],
"custom-highlight-font-metrics-002.html": [
- "48ca92feef0f8bcbaa45371afee9365cbf6ccef7",
+ "58b2db5ce4e9a12b2298c24a1deda18553da6b5f",
[
null,
[
@@ -195327,7 +195343,7 @@
[
[
0,
- 120
+ 128
],
[
0,
@@ -205937,6 +205953,32 @@
}
]
],
+ "clip-path-animation-ellipse-mixed-change.html": [
+ "e42d3ee08ed599b72be97e078b296b8f49f22e2c",
+ [
+ null,
+ [
+ [
+ "/css/css-masking/clip-path/animations/clip-path-animation-ellipse-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "clip-path-animation-ellipse.html": [
+ "1c7c90ee844551c878b2ac2dd9453cdef92fb49f",
+ [
+ null,
+ [
+ [
+ "/css/css-masking/clip-path/animations/clip-path-animation-ellipse-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"clip-path-animation-filter.html": [
"a9809cbc30b5ca53fc464a125af9bdaeaeef9c60",
[
@@ -206008,6 +206050,45 @@
}
]
],
+ "clip-path-animation-font-size-inherited.html": [
+ "6836af5a2953611798e7b4c5a80b7a4b66ee6c78",
+ [
+ null,
+ [
+ [
+ "/css/css-masking/clip-path/animations/clip-path-animation-font-size-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "clip-path-animation-font-size-mixed-change.html": [
+ "9e24aa905c2c4ba2e77d8d5ce686ddcbc57a01ad",
+ [
+ null,
+ [
+ [
+ "/css/css-masking/clip-path/animations/clip-path-animation-font-size-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "clip-path-animation-font-size.html": [
+ "00563305e54267948fc23e441420008760c26637",
+ [
+ null,
+ [
+ [
+ "/css/css-masking/clip-path/animations/clip-path-animation-font-size-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"clip-path-animation-fragmented.html": [
"9f68c238faf2ee2d04940e2f65d303bf94444595",
[
@@ -206163,6 +206244,61 @@
}
]
],
+ "clip-path-animation-path.html": [
+ "20400ba5ece395864e96ce095918f562b415566e",
+ [
+ null,
+ [
+ [
+ "/css/css-masking/clip-path/animations/clip-path-animation-path-ref.html",
+ "=="
+ ]
+ ],
+ {
+ "fuzzy": [
+ [
+ null,
+ [
+ [
+ 0,
+ 10
+ ],
+ [
+ 0,
+ 200
+ ]
+ ]
+ ]
+ ]
+ }
+ ]
+ ],
+ "clip-path-animation-polygon-mixed-change.html": [
+ "569c0af66ae3ae66ddcc185392ad66e488fdffca",
+ [
+ null,
+ [
+ [
+ "/css/css-masking/clip-path/animations/clip-path-animation-polygon-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "clip-path-animation-polygon.html": [
+ "1a9d0cc168879dfba969cc534dd7b3d9edba7c47",
+ [
+ null,
+ [
+ [
+ "/css/css-masking/clip-path/animations/clip-path-animation-polygon-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"clip-path-animation-svg-zoom.html": [
"f7be6d25324ce92e6bf56921fffb3eeec27cfd98",
[
@@ -210598,7 +210734,7 @@
]
],
"mask-image-3b.html": [
- "bd805cde975a844527eefca27d771cf5c39fc2c0",
+ "b6609fde6a4ac33ca1fb9fd6f87513e2fef9498d",
[
null,
[
@@ -210607,11 +210743,27 @@
"=="
]
],
- {}
+ {
+ "fuzzy": [
+ [
+ null,
+ [
+ [
+ 0,
+ 1
+ ],
+ [
+ 0,
+ 100
+ ]
+ ]
+ ]
+ ]
+ }
]
],
"mask-image-3c.html": [
- "32bd4454d715069524c8d6e0994aac489ccd6b22",
+ "91cc9f7bb100398e9789a39dead4bde623de18e7",
[
null,
[
@@ -210620,11 +210772,27 @@
"=="
]
],
- {}
+ {
+ "fuzzy": [
+ [
+ null,
+ [
+ [
+ 0,
+ 1
+ ],
+ [
+ 0,
+ 100
+ ]
+ ]
+ ]
+ ]
+ }
]
],
"mask-image-3d.html": [
- "f1ef1be7099b9f322aa5bf65db272d765a76be7c",
+ "468872fecbde8ec1a8b54abc7c83a7b3dfb4357b",
[
null,
[
@@ -210633,11 +210801,27 @@
"=="
]
],
- {}
+ {
+ "fuzzy": [
+ [
+ null,
+ [
+ [
+ 0,
+ 1
+ ],
+ [
+ 0,
+ 100
+ ]
+ ]
+ ]
+ ]
+ }
]
],
"mask-image-3e.html": [
- "15223e34d627e22356246f12f1717758898661d4",
+ "5e5393755453b30dd73c10ebeee3bfa95ded939b",
[
null,
[
@@ -210646,11 +210830,27 @@
"=="
]
],
- {}
+ {
+ "fuzzy": [
+ [
+ null,
+ [
+ [
+ 0,
+ 1
+ ],
+ [
+ 0,
+ 100
+ ]
+ ]
+ ]
+ ]
+ }
]
],
"mask-image-3f.html": [
- "e925105baacd81242c0bda3dd11175651e934f5b",
+ "0ecfd383652bc1a8fd57af6a1936685410dd4329",
[
null,
[
@@ -210659,11 +210859,27 @@
"=="
]
],
- {}
+ {
+ "fuzzy": [
+ [
+ null,
+ [
+ [
+ 0,
+ 1
+ ],
+ [
+ 0,
+ 100
+ ]
+ ]
+ ]
+ ]
+ }
]
],
"mask-image-3g.html": [
- "1236c0c33487ee825a2a3bb7f1b473a99fc70cea",
+ "133a69fa6094e7c002ac8340761df0244681f0fc",
[
null,
[
@@ -210672,7 +210888,23 @@
"=="
]
],
- {}
+ {
+ "fuzzy": [
+ [
+ null,
+ [
+ [
+ 0,
+ 1
+ ],
+ [
+ 0,
+ 100
+ ]
+ ]
+ ]
+ ]
+ }
]
],
"mask-image-3h.html": [
@@ -322185,7 +322417,7 @@
]
],
"lang-xmllang-01.html": [
- "9538f15ca8c808abcc5fb800ee47272367dc4e76",
+ "04d8b74e2d1260d24318f975fedc2552897e9327",
[
null,
[
@@ -322198,7 +322430,7 @@
]
],
"lang-xyzzy.html": [
- "d6e6aeb6475f3bdac8f9cfee9cb58d1c8edba86c",
+ "b950e1fac99168e76121eaa4553a014e7ed84bfb",
[
null,
[
@@ -326252,6 +326484,19 @@
{}
]
],
+ "iframe-loading-lazy-in-viewport-001.html": [
+ "408e5309e57d621ca6e486f62533bbd985de0c48",
+ [
+ null,
+ [
+ [
+ "/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-viewport-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"iframe-modify-scrolling-attr-to-yes.html": [
"9d85aa543d2d1732b8534fcdfa62a42d11716586",
[
@@ -330025,17 +330270,149 @@
]
},
"jpegxl": {
- "srgb.html": [
- "9d131787ec3aeb1619b40811464cc823397ea901",
+ "3x3_jpeg_recompression.html": [
+ "f28fca8fdce33b39ace86403a348195f910de481",
[
null,
[
[
- "/jpegxl/srgb-ref.html",
+ "/jpegxl/3x3_jpeg_recompression-ref.html",
"=="
]
],
- {}
+ {
+ "fuzzy": [
+ [
+ null,
+ [
+ [
+ 0,
+ 1
+ ],
+ [
+ 0,
+ 9
+ ]
+ ]
+ ]
+ ]
+ }
+ ]
+ ],
+ "3x3_srgb_lossless.html": [
+ "589f11c68c4152eea3d395104c0d5ce4bbefbf4d",
+ [
+ null,
+ [
+ [
+ "/jpegxl/3x3_srgb_lossless-ref.html",
+ "=="
+ ]
+ ],
+ {
+ "fuzzy": [
+ [
+ null,
+ [
+ [
+ 0,
+ 4
+ ],
+ [
+ 0,
+ 9
+ ]
+ ]
+ ]
+ ]
+ }
+ ]
+ ],
+ "3x3_srgb_lossy.html": [
+ "3a92b2b7301d35570b4349513ccc1e1318a8ca8f",
+ [
+ null,
+ [
+ [
+ "/jpegxl/3x3_srgb_lossy-ref.html",
+ "=="
+ ]
+ ],
+ {
+ "fuzzy": [
+ [
+ null,
+ [
+ [
+ 0,
+ 10
+ ],
+ [
+ 0,
+ 9
+ ]
+ ]
+ ]
+ ]
+ }
+ ]
+ ],
+ "3x3a_srgb_lossless.html": [
+ "1de61a5ba2713b0fc876305666069cb58299de29",
+ [
+ null,
+ [
+ [
+ "/jpegxl/3x3a_srgb_lossless-ref.html",
+ "=="
+ ]
+ ],
+ {
+ "fuzzy": [
+ [
+ null,
+ [
+ [
+ 0,
+ 4
+ ],
+ [
+ 0,
+ 9
+ ]
+ ]
+ ]
+ ]
+ }
+ ]
+ ],
+ "3x3a_srgb_lossy.html": [
+ "59583a11a9aab8bf4114bad2de3f405dffc3f0cd",
+ [
+ null,
+ [
+ [
+ "/jpegxl/3x3a_srgb_lossy-ref.html",
+ "=="
+ ]
+ ],
+ {
+ "fuzzy": [
+ [
+ null,
+ [
+ [
+ 0,
+ 10
+ ],
+ [
+ 0,
+ 9
+ ]
+ ]
+ ]
+ ]
+ }
]
]
},
@@ -334618,7 +334995,7 @@
]
],
"masked.html": [
- "1c7a332d7f9e21dc85105793922b725aeb3891c2",
+ "a4ca2fd8521f06808d4c2515ce007027ebcac2a4",
[
null,
[
@@ -334634,7 +335011,7 @@
[
[
0,
- 37
+ 138
],
[
0,
@@ -336314,6 +336691,21 @@
{}
]
]
+ },
+ "scripted": {
+ "pattern-transform-clear.svg": [
+ "6800fd8d20dfe3222f782140ca6106f3864e3db6",
+ [
+ null,
+ [
+ [
+ "/svg/pservers/reftests/reference/green-100x100.svg",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ]
}
},
"render": {
@@ -341148,7 +341540,7 @@
],
"workflows": {
"documentation.yml": [
- "00c7bb226279e9a3a9dfddbe224edfe55a8688b3",
+ "1d57acc6256c14b664daf1c4f528ca849b7e22b6",
[]
],
"epochs.yml": [
@@ -341625,7 +342017,13 @@
"META.yml": [
"dbfac71522fa59318abb52edc530dc850fe66936",
[]
- ]
+ ],
+ "resources": {
+ "sensor-data.js": [
+ "6f56cfdbeb6dfff65ccdbf9b6b49474c021c6ba7",
+ []
+ ]
+ }
},
"accessibility": {
"ReadMe.md": [
@@ -341793,7 +342191,13 @@
"META.yml": [
"e173970b5d77af1fcff868fa026dc2787d7a3cc0",
[]
- ]
+ ],
+ "resources": {
+ "sensor-data.js": [
+ "c1f7bd5ca0f7fb2722c17433b0dd1b0810223324",
+ []
+ ]
+ }
},
"animation-worklet": {
"META.yml": [
@@ -345024,7 +345428,7 @@
],
"resources": {
"helpers.js": [
- "c4c8c5b03261458ceabaeb7a7ed736cf812226a1",
+ "97a62309cd5b39c14ab9c31b9c1305b160ba5c7e",
[]
]
}
@@ -345438,6 +345842,10 @@
[]
]
},
+ "top-layer.js": [
+ "2dc8ce3893aa721ba1c03f4ac42ba8c52c8312f4",
+ []
+ ],
"utils.js": [
"62e742bee7f67cf3bd92a217a0a92b23fddf3017",
[]
@@ -366213,7 +366621,7 @@
],
"fedcm": {
"accounts.py": [
- "3989de7f17c6da82f8e7a41aba7947dac051df1a",
+ "126f911a58c80a62de06b6062cdb4488549471b9",
[]
],
"client_metadata.py": [
@@ -366228,6 +366636,10 @@
"3c31bf5077d73ac258f4a96bb6b4f5e95802f184",
[]
],
+ "error_with_code_and_url.py": [
+ "71bfea00f463051e7bd496cf1c28f25208e2b41e",
+ []
+ ],
"intercept_service_worker.js": [
"773e38fd21b023b8314f732b6d1893ab6c65a3cd",
[]
@@ -366248,6 +366660,10 @@
"ba9ec9c9d47e7a5888b5d987b61ff51ad66bec80",
[]
],
+ "manifest_id_assertion_endpoint_returns_error.json": [
+ "e098cc4511a1980392097d0a26c020db3243ae35",
+ []
+ ],
"manifest_redirect_accounts.json": [
"6a8972feebd6d139cb279d2f0446d4c3957bc5fc",
[]
@@ -366256,6 +366672,10 @@
"affe34f8f31f61f5cf5a5c88c0588efb331b4d1e",
[]
],
+ "manifest_token_with_http_error.json": [
+ "691a1e8d3a63a3695ec1fd29267506363871af71",
+ []
+ ],
"manifest_with_auto_selected_flag.json": [
"591c927153b9a78695ded0663fed600cbae5bcb6",
[]
@@ -366308,8 +366728,12 @@
"93ccf3ee7e2277716dc1c9d5b02805b9e2b398cc",
[]
],
+ "token_with_http_error.py": [
+ "c8d95ab63d7ebda6d32a60307f123bd858f39891",
+ []
+ ],
"two_accounts.py": [
- "4ea6d76a7eb2ea489410c672494ff7500e4046f0",
+ "4022561ff78321d91605b07f76d03a1f8deb5297",
[]
],
"userinfo-iframe.html": [
@@ -366322,7 +366746,7 @@
]
},
"fedcm-helper.sub.js": [
- "ef10e41793a16c3ead78e12a2425b5e422851906",
+ "f02a76b3fe2b39763fc8fc3be510a73bb01ed1de",
[]
],
"fedcm-iframe-level2.html": [
@@ -366334,7 +366758,7 @@
[]
],
"fedcm-mock.js": [
- "16a72b1d2c3ced916368c50c096376a319ea7a4c",
+ "b14bbaa80a72bc5157cbf80c6fa70f33e3e6e70f",
[]
],
"fedcm-mojojs-helper.js": [
@@ -366345,12 +366769,20 @@
"476f32688f91cede949edf2a1e650ef573525bd7",
[]
],
+ "fencedframe-mark-signedin.html": [
+ "532db7047a8a0903dfa8dec0fac943318c18e505",
+ []
+ ],
+ "iframe-mark-signedin.html": [
+ "4ca0125cde2e4ec7a404ba360becf22a66eb3e40",
+ []
+ ],
"mark_signedin": [
"d9adcaa762909e0ddef54daa989848169ede25dc",
[]
],
"mark_signedin.sub.headers": [
- "b87b36fa3b39fb75b986cb89d228841de6535ede",
+ "d560fade5a0e4237f751b0c90a87fc25f92aa14a",
[]
],
"mark_signedout": [
@@ -366358,7 +366790,7 @@
[]
],
"mark_signedout.sub.headers": [
- "46a8c34b2180c78ed66800d860beaa052e6c1eee",
+ "69157b3a371e369df585331a2479144fee444f5c",
[]
],
"otpcredential-helper.js": [
@@ -388241,8 +388673,8 @@
"298c4890dffede87edc4b042c13a254a15a95f53",
[]
],
- "t32-opacity-basic-0.6-a-ref.html": [
- "fb906237b23dc65f95d5d3ab1b27f5b375bc9fa5",
+ "t32-opacity-basic-0.6-a-ref.xht": [
+ "ae46348506556247a2f97a3cc1d6d3f76676a110",
[]
],
"t32-opacity-basic-1.0-a-ref.html": [
@@ -388289,6 +388721,10 @@
"b824200a06bcd4c27b05e19ae9da12ff96176a0b",
[]
],
+ "t422-rgba-a0.6-a-ref.xht": [
+ "ae46348506556247a2f97a3cc1d6d3f76676a110",
+ []
+ ],
"t422-rgba-a1.0-a-ref.html": [
"6aa32ae7bb6496f9359502feb4bcfa04bc3c8dd7",
[]
@@ -388401,8 +388837,8 @@
"ac42b1f86ce97a2e95aafe91f53cc5ff125ca73e",
[]
],
- "t425-hsla-basic-a-ref.html": [
- "32eb4cd46ccf0f66b30d986f0c054a8c32a2e4a3",
+ "t425-hsla-basic-a-ref.xht": [
+ "bc21fe36a26a573b5922aa84b9934e003bcadb49",
[]
],
"t425-hsla-clip-outside-device-gamut-b-ref.html": [
@@ -388450,11 +388886,11 @@
[]
],
"xyz-d50-003-ref.html": [
- "51f565e04b13fc35bfd39a6171f40ae193b86012",
+ "4223a511df5fa75901e01aa2758d567d7c0ce7ae",
[]
],
"xyz-d50-004-ref.html": [
- "9d211ae42a531efae3a3ec916755d260217882eb",
+ "4d1c08f2ae8052a5f6f198b7cd0f7c26e6ec6103",
[]
],
"xyz-d65-003-ref.html": [
@@ -404357,6 +404793,10 @@
"edaf92cb8ae763ed592810d19343e24a89ff1f0f",
[]
],
+ "clip-path-animation-ellipse-ref.html": [
+ "63b3174806f9751a6fcfebb3b81e508decd4ebbc",
+ []
+ ],
"clip-path-animation-filter-ref.html": [
"5bb9a9c7220f33e02b69bc7e909630ff10682de6",
[]
@@ -404369,6 +404809,10 @@
"a069e4d3ae5bc82ea9547b01e7958b8f7eead645",
[]
],
+ "clip-path-animation-font-size-ref.html": [
+ "912a8e8464266e98588bc3a6faf6b60d589198d7",
+ []
+ ],
"clip-path-animation-fragmented-ref.html": [
"8883679acaaa51a72c8b662701941fdf3a18fb3d",
[]
@@ -404397,6 +404841,14 @@
"154a56d5f07832fc7ef08b4db40acbb50faf8348",
[]
],
+ "clip-path-animation-path-ref.html": [
+ "d53067f5634265344f78962fbab011e742b0dbf3",
+ []
+ ],
+ "clip-path-animation-polygon-ref.html": [
+ "28e11e966d58ad6ed074ff1a3e8b232f56df8213",
+ []
+ ],
"clip-path-animation-ref.html": [
"b548c5d590edeef0d7aa8a8b4461fed72d2460c7",
[]
@@ -407641,7 +408093,7 @@
],
"resources": {
"utils.js": [
- "fc3a5993cf566559505c1b92c6ff08d2e9484ad0",
+ "a952a4feedc5523219eccd231c9bf1c1dc624755",
[]
]
},
@@ -426402,7 +426854,7 @@
[]
],
"formatblock.js": [
- "64e0d11d5948170f7506b20a4e646c93cc4dc63b",
+ "0161e4da01b455c698948687956ad32daa20a1a7",
[]
],
"forwarddelete.js": [
@@ -429892,7 +430344,17 @@
"README.md": [
"661e2b918438fabcdee9e160f79ba8dddb2877d4",
[]
- ]
+ ],
+ "resources": {
+ "fetch-later.html": [
+ "b569e1a076ac210d87d01b51ded0a8943476eac0",
+ []
+ ],
+ "header-referrer-helper.js": [
+ "374097614ae92646ab6260948abcc64cbdaf4d8d",
+ []
+ ]
+ }
},
"h1-parsing": {
"README.md": [
@@ -430556,12 +431018,12 @@
"fledge": {
"tentative": {
"TODO": [
- "2b6a1dc3c2d1cd64cbd84a629e0abd6148253b51",
+ "272a5e3ffb982366053c13ee0610e6a2dc5d8eab",
[]
],
"resources": {
"bidding-logic.sub.py": [
- "58fe220880a2ff054a6eabf02082a68702d6bc04",
+ "c0d6114ab2c6102ba545e92a969a1eecce696d85",
[]
],
"decision-logic.sub.py": [
@@ -430577,11 +431039,19 @@
[]
],
"fledge-util.sub.js": [
- "d500307a07939ece0c817daed5417f0cdbabcfd9",
+ "e19d85a558ff1fe885611daf7338bbead70a2012",
+ []
+ ],
+ "fledge_http_server_util.py": [
+ "a5c9c9715aa1013450b9cb60958a55c605b27701",
[]
],
"request-tracker.py": [
- "46da796f30102e0e32a82a4dab96fa9217154306",
+ "9fe20bf83ac0d83da8b26f71540151a92d10ca02",
+ []
+ ],
+ "set-cookie.asis": [
+ "96d9f07c578c34085dd789d2a11b37cd4a51c42c",
[]
],
"subordinate-frame.sub.html": [
@@ -430589,11 +431059,11 @@
[]
],
"trusted-bidding-signals.py": [
- "86e4db8ad448ade94b4c5885ea6b99b9f80e2871",
+ "16272afc71ccedb19cdcd80305fa78dc0f974b03",
[]
],
"trusted-scoring-signals.py": [
- "43ff772a0e32f2928b01db727b0c1e9988a42cec",
+ "fc6ec79096c4708b347e0cfc277fa248bf8ba9c3",
[]
]
}
@@ -432075,20 +432545,20 @@
[]
],
"generic-sensor-iframe-tests.sub.js": [
- "7b816c01c745ab7fb41f4f0d8024d34b377430d6",
+ "8f13bd778e06e58c2c8417d58c2fcb1f7cda43ed",
[]
],
"generic-sensor-tests.js": [
- "3c8f478c541dcdb28d27012574dbdeb407902a16",
+ "3b23fe89191f42f6a404d56fd50d8d9b84adeff1",
[]
],
"resources": {
"generic-sensor-helpers.js": [
- "9a51a591ce116e981310c0f1eb37cfc7eac722fd",
+ "146f4292ade4bf8fd965991c237a766b16cad84b",
[]
],
"iframe_sensor_handler.html": [
- "4528c57a6beeec84bc00e311be0691e595b2f167",
+ "80cdcf7c0d02ffe123b39b86cd2b9cdad5aee7cf",
[]
]
}
@@ -432137,7 +432607,13 @@
"META.yml": [
"939d6d076043a414d3e8dccbfc9c57830dd913be",
[]
- ]
+ ],
+ "resources": {
+ "sensor-data.js": [
+ "5bbad442929bf518930fa0294f4d270447deef1c",
+ []
+ ]
+ }
},
"graphics-aam": {
"META.yml": [
@@ -432167,7 +432643,13 @@
"META.yml": [
"8f553a86ca3bf19fe429f4a31f20d97ed8b1babd",
[]
- ]
+ ],
+ "resources": {
+ "sensor-data.js": [
+ "409ffef9a1750c4b058bafae9898e72bd9d59624",
+ []
+ ]
+ }
},
"hr-time": {
"META.yml": [
@@ -432182,6 +432664,10 @@
"5f8621ef83660c66f0d037ea28fafefb558140f1",
[]
],
+ "raf-coarsened-time.https.html.headers": [
+ "5f8621ef83660c66f0d037ea28fafefb558140f1",
+ []
+ ],
"resources": {
"clamped-time-origin.js": [
"09967ed6d17ec0c302455d878d85034046db89a2",
@@ -432337,6 +432823,16 @@
"9e917227147346f0115330c3a6bc953f47349f06",
[]
],
+ "pagereveal": {
+ "tentative": {
+ "resources": {
+ "order-in-prerender-activation-popup.html": [
+ "78989adc172997dd379ea6e7aee578be45702b79",
+ []
+ ]
+ }
+ }
+ },
"persisted-user-state-restoration": {
"resources": {
"blank1.html": [
@@ -437658,7 +438154,7 @@
[]
],
"lang-xmllang-01-ref.html": [
- "1606bca21581d9ae30fb027f59f5caa205a34c7e",
+ "eacf73da16c2e7242eed98a415ce187510e44120",
[]
],
"lang-xyzzy-ref.html": [
@@ -443361,6 +443857,10 @@
"0484c397cd4bedd92f33a4c43f8d589ace6b1557",
[]
],
+ "iframe-loading-lazy-in-viewport-ref.html": [
+ "067bfa19202b237046f0e06261f039e1a2e74b92",
+ []
+ ],
"iframe-modify-scrolling-attr-to-yes-ref.html": [
"3758ea2cab4096beccb3722a1cc534b71c662a64",
[]
@@ -444698,7 +445198,7 @@
[]
],
"popover-utils.js": [
- "f11291e5c2ff97ee03f0093d55fb33d3e18f8c99",
+ "bfc1f89ec1003bfaeca1a7aea115140858a85717",
[]
]
}
@@ -448384,6 +448884,10 @@
"adbdc7bd93d71cee1fb318dfd36a8bd5cd305892",
[]
],
+ "WEB_FEATURES.yml": [
+ "1e208f268e303c3d470467894407b3e0cde6bda4",
+ []
+ ],
"idle-detection-allowed-by-permissions-policy.https.sub.html.headers": [
"2bf18afe5fe4d034619b3e0a62455649d4203e18",
[]
@@ -449253,6 +449757,14 @@
"6505d896a9c195614a89af06af6f9c11b8c5eb7b",
[]
]
+ },
+ "webdriver": {
+ "tests": {
+ "test_load_file.py.ini": [
+ "7e6ef522c9b9544508654f63d12501560625608a",
+ []
+ ]
+ }
}
},
"update_properties.json": [
@@ -450053,7 +450565,7 @@
[]
],
"invokers.tentative.idl": [
- "67e2eb4ce196362fba16c7ab56d1168504be49c8",
+ "62f7398b82735670809610de90ad2f91a9dde06e",
[]
],
"is-input-pending.idl": [
@@ -450760,24 +451272,76 @@
}
},
"jpegxl": {
+ "3x3_jpeg_recompression-ref.html": [
+ "070243d6a7e66183f9a7bcbe77cd7263e0ecbcc0",
+ []
+ ],
+ "3x3_srgb_lossless-ref.html": [
+ "1bb50832409d6aa7a645a413622ccc5e2443bea8",
+ []
+ ],
+ "3x3_srgb_lossy-ref.html": [
+ "a5e95baba3b19607b9d7044328e4516937918784",
+ []
+ ],
+ "3x3a_srgb_lossless-ref.html": [
+ "75d8ba7452ede9efbe871e28637cc30120c88809",
+ []
+ ],
+ "3x3a_srgb_lossy-ref.html": [
+ "3a1c22e8a2775b32622ccc538e3cef14d527db5a",
+ []
+ ],
"META.yml": [
"d012c7f9bac05cd71119949a26996ae83bc65c8e",
[]
],
"resources": {
- "3x3.png": [
- "96f86420a5fe51003c039eeb906bac4927e5bd98",
+ "3x3_jpeg_recompression.jxl": [
+ "deee4257ff6729cb754cdefc5a1319e20f6ac865",
+ []
+ ],
+ "3x3_jpeg_recompression.png": [
+ "b147cb57bd8ef2ab413badd367754162fa105f75",
+ []
+ ],
+ "3x3_srgb_lossless.jxl": [
+ "bb9cf0bb2e487fb09bc394827a72f2f1c6275082",
+ []
+ ],
+ "3x3_srgb_lossless.png": [
+ "f314145a13949d190710a92e7d1c119d0ef302f5",
+ []
+ ],
+ "3x3_srgb_lossy.jxl": [
+ "a2d7a898e159b494bec5180b560eb03b0afd926b",
+ []
+ ],
+ "3x3_srgb_lossy.png": [
+ "ad5ef8117f688a05a11933a05be84bbbe0768369",
+ []
+ ],
+ "3x3a_srgb_lossless.jxl": [
+ "6bbb43d8e72f94a548d1cc38dc58981123d11979",
+ []
+ ],
+ "3x3a_srgb_lossless.png": [
+ "3c5f9c4e6b14b0e7d44e4160b3bc40cd1d51eff6",
+ []
+ ],
+ "3x3a_srgb_lossy.jxl": [
+ "0a4e952e3b83ec7f7179d12e9976d1087d9a607c",
[]
],
- "3x3_srgb.jxl": [
- "5e52b33641e1d27f2067bac9ce09894c7e903ac5",
+ "3x3a_srgb_lossy.png": [
+ "885c5d0359201ba13d49c43d311ed914bda760b3",
+ []
+ ],
+ "generate_resources.sh": [
+ "359b2afd9ea77f2d524eb0b422b9d923ca7f5cf0",
[]
]
- },
- "srgb-ref.html": [
- "634567e4303bd9ea9b2e7f347050f8036c60cb4f",
- []
- ]
+ }
},
"js": {
"META.yml": [
@@ -450988,7 +451552,7 @@
]
},
"lint.ignore": [
- "247d2950d55e7c4117728eb2881443f2b936176f",
+ "5a16051bbd4f6343d864c300cd6e3c4fcf7d4f96",
[]
],
"loading": {
@@ -451262,6 +451826,10 @@
"b7544af4e5664e05f3ae66ed939b836273a25eec",
[]
],
+ "stream-promise-generates-loaf.js": [
+ "35e7920bb20a6b02438b3f0abf8019598355af9c",
+ []
+ ],
"utils.js": [
"574af6d6b8c716ba066f49014adabe4b6e1a537a",
[]
@@ -451321,7 +451889,13 @@
"Magnetometer-enabled-on-self-origin-by-feature-policy.https.html.headers": [
"4223f53ffa3d2cd8ff4497e7018bdc9750d17a99",
[]
- ]
+ ],
+ "resources": {
+ "sensor-data.js": [
+ "32c2b1e2895b4883ee7bfb1d3042c77c12ac08c2",
+ []
+ ]
+ }
},
"managed": {
"META.yml": [
@@ -453925,9 +454499,15 @@
[]
],
"orientation-sensor-tests.js": [
- "88fd432d470d025b3dd9679e216221e5fc431b3d",
+ "d69fa3e54cdc70c60e10eb3c31ca426e3fee432b",
[]
- ]
+ ],
+ "resources": {
+ "sensor-data.js": [
+ "d0b280fa6c4371e8f854554a9b1fa3bed3a0a3d6",
+ []
+ ]
+ }
},
"page-lifecycle": {
"META.yml": [
@@ -460944,7 +461524,7 @@
[]
],
"redirect.py": [
- "bb4c874aacee9479bd690bfae8dc956378d1ee64",
+ "025ea671c503f7816f634f23cfc80c78a815aa25",
[]
]
},
@@ -460962,7 +461542,7 @@
[]
],
"worker_interception_redirect_webworker.py": [
- "bb4c874aacee9479bd690bfae8dc956378d1ee64",
+ "025ea671c503f7816f634f23cfc80c78a815aa25",
[]
]
},
@@ -461058,7 +461638,7 @@
[]
],
"worker_interception_redirect_webworker.py": [
- "bb4c874aacee9479bd690bfae8dc956378d1ee64",
+ "025ea671c503f7816f634f23cfc80c78a815aa25",
[]
]
},
@@ -462633,7 +463213,7 @@
[]
],
"helpers.js": [
- "7d259b21676329fcb3770cd7982a3342bf3bf7d3",
+ "24ed21a976b9fcb8a5539298be45e43db9736057",
[]
],
"resources": {
@@ -462642,7 +463222,11 @@
[]
],
"embedded_responder.js": [
- "634079289b01557189b1335ba7801c4eb6f6cc9b",
+ "e9cc39bc71ab658965696eb0fdbdb09827e0fa2f",
+ []
+ ],
+ "embedded_worker.js": [
+ "f3a0fb257adf204431a2df4ade796c74c0643950",
[]
],
"hasStorageAccess-ABA-iframe.https.html": [
@@ -462688,6 +463272,14 @@
"set-cookie-header.py": [
"e937ba2ca4eca2421ea0025c5a527d3bb6b574f4",
[]
+ ],
+ "storage-access-beyond-cookies-iframe-iframe.html": [
+ "348efc5dec45371cbedceac1000386ebfc3bba4f",
+ []
+ ],
+ "storage-access-beyond-cookies-iframe.sub.html": [
+ "fae51c2d547b4ea60ca1356dc9627b693a61e8a8",
+ []
]
}
},
@@ -464096,7 +464688,7 @@
[]
],
"ci_wptrunner_infrastructure.sh": [
- "ebe7870afa871fff063c206d17836156a468b420",
+ "fc6907f8de6e356dfc65850dfe08947f07bfd120",
[]
],
"commands.json": [
@@ -464148,7 +464740,7 @@
[]
],
"taskcluster-run.py": [
- "c801f61e8e8914ab2d3a20fb9ded9e3ac6b64572",
+ "2917d8f3402e218ccf868485ebcb802e40001f25",
[]
],
"tc": {
@@ -464182,7 +464774,7 @@
],
"tasks": {
"test.yml": [
- "598a3395def60e2142d91352e2ede751f1637049",
+ "7c1a4df994c94cf2b6417b84c0a76aea8445b739",
[]
]
},
@@ -464218,7 +464810,7 @@
[]
],
"test_valid.py": [
- "1d50115f91d2aaed1170f27e8fa85724592ee78b",
+ "36c2d0a986c36f128e9dbd950343feec20822069",
[]
]
}
@@ -464720,7 +465312,7 @@
[]
],
"update_manifest.py": [
- "a7f72b35b339a054482dbb35a444cdcf63e1a9fd",
+ "58b9ac4d84bfbddec73de67a0618389939142615",
[]
]
},
@@ -472431,7 +473023,7 @@
],
"webdriver": {
"__init__.py": [
- "a81751407e70cbfc0637cf23b6641b078b5aac23",
+ "dfd264f8b2990a9d1e5dd851cac9d3c6a9176c1e",
[]
],
"bidi": {
@@ -472487,7 +473079,7 @@
]
},
"client.py": [
- "f33fc34dac9ee53135239ef906b1e88b6f4c6114",
+ "e41df7f57640a6e40963de638872c130eae5d71d",
[]
],
"error.py": [
@@ -472495,11 +473087,11 @@
[]
],
"protocol.py": [
- "1972c3fce2167b23ce515a295053c5e3447fa9ed",
+ "d6c89af22be2eb72068f4e59ab0040e5cbce1fd2",
[]
],
"transport.py": [
- "e1e16bdebadd5ac02a8c3ee744a078a6a4b7668d",
+ "ca1ff74ef96767afa76c200b159671d99762cb84",
[]
]
}
@@ -472698,7 +473290,7 @@
[]
],
"utils.py": [
- "b015b95e1ae2088b6d7a0b671cd75b61a8f0f424",
+ "5899dc3f3a967ff7d4b8b3c9e5340428ba6a9de8",
[]
],
"virtualenv.py": [
@@ -472746,7 +473338,7 @@
]
},
"requirements.txt": [
- "1c4316a9f8676ac527dfcd29e0db9793b36154a9",
+ "93c17bf3bff2dfeb73fc0f419926d893b0dc72f3",
[]
],
"requirements_chromium.txt": [
@@ -472828,7 +473420,7 @@
[]
],
"content_shell.py": [
- "14956eeb786b09f411dfb7a8a37379891e574c46",
+ "23f4e99da62291005bb94450cde7d5ce592288a0",
[]
],
"edge.py": [
@@ -472924,7 +473516,7 @@
[]
],
"base.py": [
- "1e66e60890e347acdd69644739f636046343ea92",
+ "e89b57b57acc533d57136fcb1c213f193f90bfca",
[]
],
"executorchrome.py": [
@@ -473079,7 +473671,7 @@
[]
],
"stability.py": [
- "9ac6249c44cba029f92f39ce35e70aa226f9790e",
+ "029b237f98815d7a737706e7e655ea8999662ce0",
[]
],
"testdriver-extra.js": [
@@ -473119,7 +473711,7 @@
[]
],
"testrunner.py": [
- "b84f1a52be3c25aa755d490b6c25862a4c17869b",
+ "a4f759c42a784e65eef8c8c1cfafc9b5105d8945",
[]
],
"tests": {
@@ -473189,6 +473781,10 @@
"59aaaeadff7934b439029c8b1124e826dc0e8090",
[]
],
+ "test_wptrunner.py": [
+ "3c9a0bc1fd41de2c9f7fd6c62dbcc700f9a22c4c",
+ []
+ ],
"test_wpttest.py": [
"d2f68361bf853fd96ae3e5da7f514f853b81152c",
[]
@@ -473299,7 +473895,7 @@
}
},
"wptrunner.py": [
- "a4ad268dce10a62a41737679dffba4b53c51b113",
+ "b9e5190105c1ab21dceed9c0c301a723c996e7f3",
[]
],
"wpttest.py": [
@@ -474712,7 +475308,7 @@
}
},
"instanceTestFactory.js": [
- "6e6ec875bda4100a22b18f4059d22f35514843fd",
+ "2e015af8198a6112a528640bdc6c202dd5785c25",
[]
],
"memory": {
@@ -474728,7 +475324,7 @@
]
},
"wasm-module-builder.js": [
- "3545c3a8da7bc9cec9798c261df953dfb5ad86c8",
+ "1d8db0a6e6fd71059963e4a1b767d796fa1a5eff",
[]
]
},
@@ -476079,7 +476675,7 @@
},
"webcodecs": {
"META.yml": [
- "8570ee05e5a29b7835b28f9113db32b9677ca535",
+ "071ef88121b4033970b22d40db581e0ca7ed5c16",
[]
],
"README.md": [
@@ -476317,6 +476913,12 @@
[]
]
},
+ "context_destroyed": {
+ "__init__.py": [
+ "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+ []
+ ]
+ },
"create": {
"__init__.py": [
"e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
@@ -477103,7 +477705,7 @@
[]
],
"asserts.py": [
- "04bd1993316be1bb449c81ccb22f0f623e38d215",
+ "9d31ff7b124347b73c47f83cd3e9725ad48f1482",
[]
],
"defaults.py": [
@@ -481889,41 +482491,41 @@
],
"auth1": {
"auth.py": [
- "db4f7bc4c9fee9a31ff07a9708d6f6299f716c93",
+ "3797aaa52e9556387053712019550ee66af88f08",
[]
]
},
"auth10": {
"auth.py": [
- "db4f7bc4c9fee9a31ff07a9708d6f6299f716c93",
+ "568d31e90687f1442ea6253fd24a4aae78934171",
[]
]
},
"auth11": {
"auth.py": [
- "db4f7bc4c9fee9a31ff07a9708d6f6299f716c93",
+ "3797aaa52e9556387053712019550ee66af88f08",
[]
]
},
"auth2": {
"auth.py": [
- "db4f7bc4c9fee9a31ff07a9708d6f6299f716c93",
+ "568d31e90687f1442ea6253fd24a4aae78934171",
[]
],
"corsenabled.py": [
- "bec6687dbe96c4acef0476e2ef3eecd7ab523c7a",
+ "7b9d3b65aba244e5c9f353bb56b8843bd91e00ed",
[]
]
},
"auth3": {
"auth.py": [
- "db4f7bc4c9fee9a31ff07a9708d6f6299f716c93",
+ "3797aaa52e9556387053712019550ee66af88f08",
[]
]
},
"auth4": {
"auth.py": [
- "db4f7bc4c9fee9a31ff07a9708d6f6299f716c93",
+ "3797aaa52e9556387053712019550ee66af88f08",
[]
]
},
@@ -481941,19 +482543,19 @@
},
"auth7": {
"corsenabled.py": [
- "7a060627b70df5c77d5fb21ca24296bbc76cb3ea",
+ "c82ba4e6bc457df08bb361da904605776b34c652",
[]
]
},
"auth8": {
"corsenabled-no-authorize.py": [
- "af8e7c4c170aa80e8eb2d19c0caedd5825862b2e",
+ "4fdf99e2658ce8a858c8c633640fa671cb9f8976",
[]
]
},
"auth9": {
"auth.py": [
- "db4f7bc4c9fee9a31ff07a9708d6f6299f716c93",
+ "3797aaa52e9556387053712019550ee66af88f08",
[]
]
},
@@ -495836,10 +496438,11 @@
]
],
"Accelerometer-iframe-access.https.html": [
- "bec1705780f53e795949729a19bf8f3e4f03b432",
+ "56005696a7f5fb70ed5dd2c25fd5db75a4bf1c0c",
[
null,
{
+ "testdriver": true,
"timeout": "long"
}
]
@@ -495852,10 +496455,11 @@
]
],
"Accelerometer.https.html": [
- "0db87d2efc3dd1a299898ec566b9c81458363b99",
+ "d422fef7264a6e301ca3f583389d632e7776a4c9",
[
null,
{
+ "testdriver": true,
"timeout": "long"
}
]
@@ -495868,19 +496472,21 @@
]
],
"GravitySensor.https.html": [
- "6fb21e5572813ea6384a4ad5c679d161fceceb7b",
+ "0f98f3e00dec4038126d1451905ac9d77d90b22a",
[
null,
{
+ "testdriver": true,
"timeout": "long"
}
]
],
"LinearAccelerationSensor.https.html": [
- "8dd3446f409169c044543b65f79a19f48fc5d1c0",
+ "91035cc9628bad32f411fdc6139915931a5641fb",
[
null,
{
+ "testdriver": true,
"timeout": "long"
}
]
@@ -496059,10 +496665,12 @@
]
],
"AmbientLightSensor-iframe-access.https.html": [
- "5fedd5fb7a9b18ac36b75802667814097c23121e",
+ "765c1bee1f818924af037d8eb4e963198a464504",
[
null,
- {}
+ {
+ "testdriver": true
+ }
]
],
"AmbientLightSensor-supported-by-feature-policy.html": [
@@ -496073,10 +496681,11 @@
]
],
"AmbientLightSensor.https.html": [
- "a8c65e4d3faf710bdc0064c5c968e1f486fe56ea",
+ "f2ed655082ed383b1c16bb5bec9f67e0950836f5",
[
null,
{
+ "testdriver": true,
"timeout": "long"
}
]
@@ -505170,7 +505779,7 @@
]
],
"clipboard-item.https.html": [
- "9ed6f583bde5ce54877b5dbfab6549cff68dffbc",
+ "b50a1c97d746168fd4166726ead0964faa03aa39",
[
null,
{}
@@ -505466,25 +506075,7 @@
]
],
"closewatcher-dialog-popover.html": [
- "f6443c4317ebd704c48ecff0ae377519d3159e2c",
- [
- null,
- {
- "testdriver": true
- }
- ]
- ],
- "dialog-cancel-events-closewatcher.html": [
- "5b1da9a2e37811e389e60ddbc358fa99e89817a6",
- [
- null,
- {
- "testdriver": true
- }
- ]
- ],
- "dialog-cancel-preventDefault-closewatcher.html": [
- "ef99578ca97dfa2f6ad48d577133b2ab6bf4157b",
+ "50d5cb7a4ca9425838f07d1ec916bb60e704b23a",
[
null,
{
@@ -505563,7 +506154,7 @@
]
],
"user-activation-shared.html": [
- "6ecc2dc694d7486c18523be2d2301d30a306d1bc",
+ "77e748532a3309f16f2cd1203119b4a92ce24262",
[
"close-watcher/user-activation-shared.html?CloseWatcher",
{
@@ -512691,10 +513282,12 @@
]
],
"prefetch-generate-directives.html": [
- "b08d885c1ecc5eff19c7bc8aa3c45fd0c415ed46",
+ "75c9485f0d77dcb51d9cdefa370dc0163c1ef2e3",
[
null,
- {}
+ {
+ "timeout": "long"
+ }
]
],
"prefetch-ignores-prefetch-src.sub.html": [
@@ -516673,8 +517266,17 @@
{}
]
],
+ "fedcm-domainhint.https.html": [
+ "d8ab79b2c5c78d6d82e9af2f1919f2a2953dc78d",
+ [
+ null,
+ {
+ "testdriver": true
+ }
+ ]
+ ],
"fedcm-endpoint-redirects.https.html": [
- "4aebc17f1ba6e7c407d708444708e2bb21bf8459",
+ "21d0a5867a76d810782d5ca06f34fc5aa518040d",
[
null,
{
@@ -516682,8 +517284,8 @@
}
]
],
- "fedcm-hosteddomain.https.html": [
- "5e39542fdef72dac98d52968fbe10f6e95d38986",
+ "fedcm-error-basic.https.html": [
+ "18ab82d0bd7f976477a9db21ac1a2e8d667ee483",
[
null,
{
@@ -516709,7 +517311,7 @@
]
],
"cross-origin-status.https.html": [
- "7c839306a479510d91d3cf6a8e379e43bb703c71",
+ "09a4aa31c6b2ba0680ec6b14d0e661dd93abb69b",
[
null,
{
@@ -516903,6 +517505,24 @@
}
]
],
+ "fedcm-store.https.html": [
+ "d1e6ef464c4f3eb8e2d4118d1a5e2dc498410e05",
+ [
+ null,
+ {
+ "testdriver": true
+ }
+ ]
+ ],
+ "fedcm-token-returned-with-http-error.https.html": [
+ "2337829add9f283983c78d9617941c18e74acb46",
+ [
+ null,
+ {
+ "testdriver": true
+ }
+ ]
+ ],
"fedcm-userinfo.https.html": [
"d460d82845282f00e0164590c552bcd73ca15255",
[
@@ -516956,6 +517576,13 @@
{}
]
],
+ "otpcredential-store.https.html": [
+ "fa2ae8933d354a16f872f3f38398989d1e927d06",
+ [
+ null,
+ {}
+ ]
+ ],
"passwordcredential-framed-get.sub.https.html": [
"b4afc1eb91e563ef59dd540dd1f6d90b2a59c854",
[
@@ -522092,7 +522719,7 @@
]
],
"nested-color-mix-with-currentcolor.html": [
- "a4dd687dd5814af2e4660586a2c97c09ba34ffe4",
+ "2f24d62b547fb24200fa659d27a9e55777303aa5",
[
null,
{}
@@ -522114,7 +522741,7 @@
]
],
"color-computed-color-mix-function.html": [
- "a48d6b20bcd0f2976e7c90069c7d994adc285304",
+ "cd5837d8b28dc587d700ad8cda232e4760b7b0cc",
[
null,
{}
@@ -522372,6 +522999,13 @@
null,
{}
]
+ ],
+ "system-color-support.html": [
+ "a17ab6ab6eeea76f29e0015aab1600115e613331",
+ [
+ null,
+ {}
+ ]
]
},
"css-color-adjust": {
@@ -526674,8 +527308,15 @@
},
"css-fonts": {
"animations": {
+ "font-palette-animation-not-specified-endpoints.html": [
+ "f3d103983c6747b28369704e81cff40f85674fab",
+ [
+ null,
+ {}
+ ]
+ ],
"font-palette-interpolation.html": [
- "66b0f00ebf01dac4cb4ad12aea9eece0d67b06f0",
+ "43e1368412e205c7ee22a326f3cfcb99a4f434e7",
[
null,
{}
@@ -531590,7 +532231,7 @@
],
"parsing": {
"gradient-interpolation-method-computed.html": [
- "9593a59777a5792332ba07d6cf4687eed09a0747",
+ "b4f8dee4393d0d11bbfbf438b8a3633f391707c3",
[
null,
{}
@@ -533127,6 +533768,13 @@
{}
]
],
+ "mask-computed.html": [
+ "28fc38defae2e5ea7b4bffab2a8755535921fa9d",
+ [
+ null,
+ {}
+ ]
+ ],
"mask-invalid.html": [
"f9999ca98284eba958eeb5236282fa3b852f41be",
[
@@ -533191,7 +533839,7 @@
]
],
"mask-valid.sub.html": [
- "a377060ded8e6ee3b8ac4ede1b13378a0a24f2cb",
+ "c4d2d4eb2c039ab59712ead6f7577606837bf5c9",
[
null,
{}
@@ -535354,7 +536002,7 @@
]
],
"custom-property-animation-transform-list-multiple-values.html": [
- "9ffaec830f8eae0a58fbadb64038b10af1efda64",
+ "1b2fc907f2548fffa8a9c71b3cfe63fa766506b0",
[
null,
{}
@@ -535367,6 +536015,13 @@
{}
]
],
+ "custom-property-animation-transform-none.tentative.html": [
+ "37abddd2271c6a28f954435b456c10c2a66ffdbf",
+ [
+ null,
+ {}
+ ]
+ ],
"custom-property-animation-url.html": [
"830b9e1f4966b865c6bc1b5bde6358f335685ea3",
[
@@ -535500,6 +536155,34 @@
{}
]
],
+ "custom-property-transition-transform-function-box-size.tentative.html": [
+ "23ac09b1fc9be7d6dea818c40c6391db20eb0491",
+ [
+ null,
+ {}
+ ]
+ ],
+ "custom-property-transition-transform-function-matrix.html": [
+ "00b5018142524fc358ee3bd932c04cffb6784201",
+ [
+ null,
+ {}
+ ]
+ ],
+ "custom-property-transition-transform-function-none.tentative.html": [
+ "29a5715fec89311b0413b3b71febda74737f4ed4",
+ [
+ null,
+ {}
+ ]
+ ],
+ "custom-property-transition-transform-function-to-list.html": [
+ "d09fb6416ac972722afa259e899c0fb1ce26e371",
+ [
+ null,
+ {}
+ ]
+ ],
"custom-property-transition-transform-function.html": [
"17ad1067a4dcfcf4f11b2f1e1a0367b1cf45ec96",
[
@@ -535507,6 +536190,27 @@
{}
]
],
+ "custom-property-transition-transform-list-box-size.tentative.html": [
+ "d1b882f70840686d0695880b45f6889c5cfdc532",
+ [
+ null,
+ {}
+ ]
+ ],
+ "custom-property-transition-transform-list-matrix.html": [
+ "8f1fa8429485fc30ecadcc87bd8308f87f414616",
+ [
+ null,
+ {}
+ ]
+ ],
+ "custom-property-transition-transform-list-none.tentative.html": [
+ "d09f5854b308b35d8aeb63b99dd385319191aeb8",
+ [
+ null,
+ {}
+ ]
+ ],
"custom-property-transition-transform-list.html": [
"c9d3cb94d143d2fd45e1a6b70b40f14538d32353",
[
@@ -536335,6 +537039,20 @@
{}
]
],
+ "after-scrollable-range-shrinkage-003.html": [
+ "c9127e79b5a42a94a0693f1b8a5d43acb03194d9",
+ [
+ null,
+ {}
+ ]
+ ],
+ "after-scrollable-range-shrinkage-004.html": [
+ "8509a1cca5e9a704e321d6084e02de63771f1785",
+ [
+ null,
+ {}
+ ]
+ ],
"ancestor-change-heuristic.html": [
"21adfbb6b7a56c0a098eda1843897926afb363f5",
[
@@ -537422,6 +538140,13 @@
]
},
"scroll-start-target": {
+ "scroll-start-target-aligns-with-snap-align.tentative.html": [
+ "6b133dea7d722bb77dde669ef2ef6c666c35551e",
+ [
+ null,
+ {}
+ ]
+ ],
"scroll-start-target-display-toggled.tentative.html": [
"527d7502678bab30c64cd351a2f76d56c50dd1f5",
[
@@ -542084,7 +542809,7 @@
}
},
"inheritance.html": [
- "83d1d4971eaf0fe9a1982df3c930cd8545944c87",
+ "2043afe999db7be2b519aeeb9ec03cc75241e4e2",
[
null,
{}
@@ -542508,6 +543233,13 @@
{}
]
],
+ "text-wrap-computed.html": [
+ "772f0abf4d975c04c582a1e36ac9b587a24e954b",
+ [
+ null,
+ {}
+ ]
+ ],
"text-wrap-invalid.html": [
"b67cecc183069358448e9ef9e5bbb9ddb064ba75",
[
@@ -542515,6 +543247,48 @@
{}
]
],
+ "text-wrap-mode-computed.html": [
+ "35e082b6474640710137f67982e1ff48c2e4037d",
+ [
+ null,
+ {}
+ ]
+ ],
+ "text-wrap-mode-invalid.html": [
+ "d63c1901c1196af37f41f603a1b30dd53d988ef2",
+ [
+ null,
+ {}
+ ]
+ ],
+ "text-wrap-mode-valid.html": [
+ "5dde8b377fb366422c709577ebb0b53bdc4dd6b6",
+ [
+ null,
+ {}
+ ]
+ ],
+ "text-wrap-style-computed.html": [
+ "0a4a22d9c5f7c1b4e7e3b7caa3774b32a69f31b6",
+ [
+ null,
+ {}
+ ]
+ ],
+ "text-wrap-style-invalid.html": [
+ "dcda82e465d22b1c1a30ef137589384fb763028b",
+ [
+ null,
+ {}
+ ]
+ ],
+ "text-wrap-style-valid.html": [
+ "b3ca09ef2c638bd178af31cc57dcd84003b8976e",
+ [
+ null,
+ {}
+ ]
+ ],
"text-wrap-valid.html": [
"a2eed8c429fa1d593ad3883f1d82ff0395d8aa49",
[
@@ -548532,7 +549306,7 @@
]
],
"round-mod-rem-computed.html": [
- "320ab4a11a92ff5b3e567187cbd5f756b8c07a9c",
+ "eb6dfe4e8ce50d54322fbef7f211ebe3febf5cb6",
[
null,
{}
@@ -551006,7 +551780,7 @@
]
],
"checkVisibility.html": [
- "c0146dc14e152cb7165609867c677a182419a677",
+ "c7bd5b69686c2d03b650fbb1a9f2124c1cad982b",
[
null,
{}
@@ -552940,7 +553714,7 @@
]
],
"dir-pseudo-on-input-element.html": [
- "db528d4079b83d352c9470d160aef130930190e8",
+ "f4a0de193a06dd4bc309d83b09ce2ac3c00961fd",
[
null,
{}
@@ -560151,20 +560925,6 @@
]
},
"domxpath": {
- "001.html": [
- "4931417af301029c5bffb64093ab8ed382890753",
- [
- null,
- {}
- ]
- ],
- "002.html": [
- "c5c1fcc52923ab38729a3e9dc74ecb0a0d70ca9e",
- [
- null,
- {}
- ]
- ],
"booleans.html": [
"41522edf05f8bc752408eb2cdde10a05bd211a7a",
[
@@ -560298,6 +561058,20 @@
{}
]
],
+ "text-html-attributes.html": [
+ "2157dcd2d68c5701b47ba907f7b1c3b2176f9239",
+ [
+ null,
+ {}
+ ]
+ ],
+ "text-html-elements.html": [
+ "b895323fbad6bfee9a9c108b1aa3d9c85d2a1e42",
+ [
+ null,
+ {}
+ ]
+ ],
"xml_xpath_runner.html": [
"03edf50515c231a9f9fbf0a0587261627b949e19",
[
@@ -560350,7 +561124,7 @@
]
],
"edit-context-input.tentative.html": [
- "0f05606a3564b4e27644e0035d42076ff6d1fda0",
+ "f65dfbc915de7ba9f50917768daa40d99687007e",
[
null,
{
@@ -588884,6 +589658,124 @@
{}
]
],
+ "headers": {
+ "header-referrer-no-referrer-when-downgrade.tentative.https.html": [
+ "38eada4513c4f17ee29bf10ccac750595e2d1e81",
+ [
+ null,
+ {}
+ ]
+ ],
+ "header-referrer-no-referrer.tentative.https.html": [
+ "75e9ece7ba511e4ba214427f63c0211d39006d50",
+ [
+ null,
+ {}
+ ]
+ ],
+ "header-referrer-origin-when-cross-origin.tentative.https.html": [
+ "b9f14171ba39671e6c258ecd0680398d19123ddd",
+ [
+ null,
+ {}
+ ]
+ ],
+ "header-referrer-origin.tentative.https.html": [
+ "ce7abf92039124d375d0a76302ce20bb0b672466",
+ [
+ null,
+ {}
+ ]
+ ],
+ "header-referrer-same-origin.tentative.https.html": [
+ "264beddc03a1b8a5933d7d657a0bc96c3f912f44",
+ [
+ null,
+ {}
+ ]
+ ],
+ "header-referrer-strict-origin-when-cross-origin.tentative.https.html": [
+ "9133f2496fe0a88f7d7b5c896a67d5fcffe60089",
+ [
+ null,
+ {}
+ ]
+ ],
+ "header-referrer-strict-origin.tentative.https.html": [
+ "943d70bbc583002c0b5a740cfe07f5f6c97c1319",
+ [
+ null,
+ {}
+ ]
+ ],
+ "header-referrer-unsafe-url.tentative.https.html": [
+ "a602e0003a49f1e10449eeecdc5507a7273d5e30",
+ [
+ null,
+ {}
+ ]
+ ]
+ },
+ "iframe.tentative.https.window.js": [
+ "62505bc81d99e6f6b6c3b93b33f7c8963e0ffe17",
+ [
+ "fetch/fetch-later/iframe.tentative.https.window.html",
+ {
+ "script_metadata": [
+ [
+ "script",
+ "/resources/testharness.js"
+ ],
+ [
+ "script",
+ "/resources/testharnessreport.js"
+ ],
+ [
+ "script",
+ "/common/utils.js"
+ ],
+ [
+ "script",
+ "/common/get-host-info.sub.js"
+ ],
+ [
+ "script",
+ "/pending-beacon/resources/pending_beacon-helper.js"
+ ]
+ ]
+ }
+ ]
+ ],
+ "new-window.tentative.https.window.js": [
+ "37b38d7f1dc075535ac9ab9beeee8809e956f8f0",
+ [
+ "fetch/fetch-later/new-window.tentative.https.window.html",
+ {
+ "script_metadata": [
+ [
+ "script",
+ "/resources/testharness.js"
+ ],
+ [
+ "script",
+ "/resources/testharnessreport.js"
+ ],
+ [
+ "script",
+ "/common/utils.js"
+ ],
+ [
+ "script",
+ "/common/get-host-info.sub.js"
+ ],
+ [
+ "script",
+ "/pending-beacon/resources/pending_beacon-helper.js"
+ ]
+ ]
+ }
+ ]
+ ],
"non-secure.window.js": [
"2f2c3ea8d34b9dfaf8bbc6b12acc304a4beb791d",
[
@@ -588902,6 +589794,110 @@
}
]
],
+ "policies": {
+ "csp-allowed.tentative.https.window.js": [
+ "5aa759c2346bd76b6ecc5c04dc5094b7a48297fa",
+ [
+ "fetch/fetch-later/policies/csp-allowed.tentative.https.window.html",
+ {
+ "script_metadata": [
+ [
+ "title",
+ "FetchLater: allowed by CSP"
+ ],
+ [
+ "script",
+ "/resources/testharness.js"
+ ],
+ [
+ "script",
+ "/resources/testharnessreport.js"
+ ],
+ [
+ "script",
+ "/common/utils.js"
+ ],
+ [
+ "script",
+ "/common/get-host-info.sub.js"
+ ],
+ [
+ "script",
+ "/pending-beacon/resources/pending_beacon-helper.js"
+ ]
+ ]
+ }
+ ]
+ ],
+ "csp-blocked.tentative.https.window.js": [
+ "88490950d3a4ec8b10e6430aacdf74116cb1e680",
+ [
+ "fetch/fetch-later/policies/csp-blocked.tentative.https.window.html",
+ {
+ "script_metadata": [
+ [
+ "title",
+ "FetchLater: blocked by CSP"
+ ],
+ [
+ "script",
+ "/resources/testharness.js"
+ ],
+ [
+ "script",
+ "/resources/testharnessreport.js"
+ ],
+ [
+ "script",
+ "/common/utils.js"
+ ],
+ [
+ "script",
+ "/common/get-host-info.sub.js"
+ ],
+ [
+ "script",
+ "/pending-beacon/resources/pending_beacon-helper.js"
+ ]
+ ]
+ }
+ ]
+ ],
+ "csp-redirect-to-blocked.tentative.https.window.js": [
+ "c2019881cc2e277d93b7b94955e5978079551f35",
+ [
+ "fetch/fetch-later/policies/csp-redirect-to-blocked.tentative.https.window.html",
+ {
+ "script_metadata": [
+ [
+ "title",
+ "FetchLater: redirect blocked by CSP"
+ ],
+ [
+ "script",
+ "/resources/testharness.js"
+ ],
+ [
+ "script",
+ "/resources/testharnessreport.js"
+ ],
+ [
+ "script",
+ "/common/utils.js"
+ ],
+ [
+ "script",
+ "/common/get-host-info.sub.js"
+ ],
+ [
+ "script",
+ "/pending-beacon/resources/pending_beacon-helper.js"
+ ]
+ ]
+ }
+ ]
+ ]
+ },
"quota.tentative.https.window.js": [
"4fc5979374c0e214f44d28982c7f22b86454d22f",
[
@@ -588933,7 +589929,7 @@
]
],
"send-on-deactivate.tentative.https.window.js": [
- "7a1ddc7ac3dac0e4be1a42ee6b7a51d6ab86c725",
+ "173c95ac12037c1dd7c7b20ca087a03f81bba8f3",
[
"fetch/fetch-later/send-on-deactivate.tentative.https.window.html",
{
@@ -588975,7 +589971,7 @@
]
],
"send-on-discard.tentative.https.window.js": [
- "c4911b110551698dd761ed86e4f50ffbb5858638",
+ "e1ff9b9e3a68e9672fd87b0a098f74bf8e344452",
[
"fetch/fetch-later/send-on-discard.tentative.https.window.html",
{
@@ -593308,7 +594304,7 @@
]
],
"auction-config.https.window.js": [
- "e4811b969651d129c2761a2e418c3ea97f574bb8",
+ "432be9cb10a5bcc456013c78f9686c563b1c77a6",
[
"fledge/tentative/auction-config.https.window.html?1-5",
{
@@ -593351,7 +594347,11 @@
],
[
"variant",
- "?21-last"
+ "?21-25"
+ ],
+ [
+ "variant",
+ "?26-last"
]
],
"timeout": "long"
@@ -593399,7 +594399,11 @@
],
[
"variant",
- "?21-last"
+ "?21-25"
+ ],
+ [
+ "variant",
+ "?26-last"
]
],
"timeout": "long"
@@ -593447,14 +594451,70 @@
],
[
"variant",
- "?21-last"
+ "?21-25"
+ ],
+ [
+ "variant",
+ "?26-last"
+ ]
+ ],
+ "timeout": "long"
+ }
+ ],
+ [
+ "fledge/tentative/auction-config.https.window.html?21-25",
+ {
+ "script_metadata": [
+ [
+ "script",
+ "/resources/testdriver.js"
+ ],
+ [
+ "script",
+ "/common/utils.js"
+ ],
+ [
+ "script",
+ "resources/fledge-util.sub.js"
+ ],
+ [
+ "script",
+ "/common/subset-tests.js"
+ ],
+ [
+ "timeout",
+ "long"
+ ],
+ [
+ "variant",
+ "?1-5"
+ ],
+ [
+ "variant",
+ "?6-10"
+ ],
+ [
+ "variant",
+ "?11-15"
+ ],
+ [
+ "variant",
+ "?16-20"
+ ],
+ [
+ "variant",
+ "?21-25"
+ ],
+ [
+ "variant",
+ "?26-last"
]
],
"timeout": "long"
}
],
[
- "fledge/tentative/auction-config.https.window.html?21-last",
+ "fledge/tentative/auction-config.https.window.html?26-last",
{
"script_metadata": [
[
@@ -593495,7 +594555,11 @@
],
[
"variant",
- "?21-last"
+ "?21-25"
+ ],
+ [
+ "variant",
+ "?26-last"
]
],
"timeout": "long"
@@ -593543,7 +594607,11 @@
],
[
"variant",
- "?21-last"
+ "?21-25"
+ ],
+ [
+ "variant",
+ "?26-last"
]
],
"timeout": "long"
@@ -594087,6 +595155,81 @@
}
]
],
+ "currency.https.window.js": [
+ "97802ce1379eb2758621c3d5753e4f302df70ed3",
+ [
+ "fledge/tentative/currency.https.window.html?1-4",
+ {
+ "script_metadata": [
+ [
+ "script",
+ "/resources/testdriver.js"
+ ],
+ [
+ "script",
+ "/common/utils.js"
+ ],
+ [
+ "script",
+ "resources/fledge-util.sub.js"
+ ],
+ [
+ "script",
+ "/common/subset-tests.js"
+ ],
+ [
+ "timeout",
+ "long"
+ ],
+ [
+ "variant",
+ "?1-4"
+ ],
+ [
+ "variant",
+ "?5-last"
+ ]
+ ],
+ "timeout": "long"
+ }
+ ],
+ [
+ "fledge/tentative/currency.https.window.html?5-last",
+ {
+ "script_metadata": [
+ [
+ "script",
+ "/resources/testdriver.js"
+ ],
+ [
+ "script",
+ "/common/utils.js"
+ ],
+ [
+ "script",
+ "resources/fledge-util.sub.js"
+ ],
+ [
+ "script",
+ "/common/subset-tests.js"
+ ],
+ [
+ "timeout",
+ "long"
+ ],
+ [
+ "variant",
+ "?1-4"
+ ],
+ [
+ "variant",
+ "?5-last"
+ ]
+ ],
+ "timeout": "long"
+ }
+ ]
+ ],
"fetch-ad-auction-headers-insecure-context.tentative.http.html": [
"d3bdb8017579414aee39ad672519ff029f9d0827",
[
@@ -594259,7 +595402,7 @@
]
],
"join-leave-ad-interest-group.https.window.js": [
- "77da23a7a5b9d79f0fe149bfb137b97a75445ce2",
+ "107bd3b815ada1b175c1ca425f6bbdb0c2e3be44",
[
"fledge/tentative/join-leave-ad-interest-group.https.window.html?1-10",
{
@@ -594837,6 +595980,89 @@
}
]
],
+ "network.https.window.js": [
+ "9c29610578664a026ad5d9d73e3cb295569424cb",
+ [
+ "fledge/tentative/network.https.window.html?1-5",
+ {
+ "script_metadata": [
+ [
+ "script",
+ "/resources/testdriver.js"
+ ],
+ [
+ "script",
+ "/resources/testdriver-vendor.js"
+ ],
+ [
+ "script",
+ "/common/subset-tests.js"
+ ],
+ [
+ "script",
+ "/common/utils.js"
+ ],
+ [
+ "script",
+ "resources/fledge-util.sub.js"
+ ],
+ [
+ "timeout",
+ "long"
+ ],
+ [
+ "variant",
+ "?1-5"
+ ],
+ [
+ "variant",
+ "?6-last"
+ ]
+ ],
+ "timeout": "long"
+ }
+ ],
+ [
+ "fledge/tentative/network.https.window.html?6-last",
+ {
+ "script_metadata": [
+ [
+ "script",
+ "/resources/testdriver.js"
+ ],
+ [
+ "script",
+ "/resources/testdriver-vendor.js"
+ ],
+ [
+ "script",
+ "/common/subset-tests.js"
+ ],
+ [
+ "script",
+ "/common/utils.js"
+ ],
+ [
+ "script",
+ "resources/fledge-util.sub.js"
+ ],
+ [
+ "timeout",
+ "long"
+ ],
+ [
+ "variant",
+ "?1-5"
+ ],
+ [
+ "variant",
+ "?6-last"
+ ]
+ ],
+ "timeout": "long"
+ }
+ ]
+ ],
"no-winner.https.window.js": [
"f252aece5bff52572395a64255f945f0030a6c72",
[
@@ -598990,7 +600216,7 @@
]
],
"fullscreen-reordering.html": [
- "4b394bc20fc1a3ce9c904eed1c23be00789d3131",
+ "1aaf3c37c04703e226b0a8fa660692eb2ba109f1",
[
null,
{
@@ -599499,10 +600725,12 @@
]
],
"GeolocationSensor-iframe-access.https.html": [
- "bb0541de32c374c0028de72c90cc195f02979d61",
+ "a3d39e3606f907ec132c075e7e5dbc96ed89c999",
[
null,
- {}
+ {
+ "testdriver": true
+ }
]
],
"GeolocationSensor-supported-by-feature-policy.html": [
@@ -599513,10 +600741,12 @@
]
],
"GeolocationSensor.https.html": [
- "b71f964b1297f39257c1e80ce50a145c5283228f",
+ "3b4b94e5bbbcc7d46b98313b71f1cb003f887c13",
[
null,
- {}
+ {
+ "testdriver": true
+ }
]
],
"GeolocationSensor_insecure_context.html": [
@@ -599600,10 +600830,12 @@
]
],
"Gyroscope-iframe-access.https.html": [
- "ed0183bef9ad414b451acc87712acd7b7b55a347",
+ "c94016764d5176b0703e1b19cd3f4cdbe0c43eb4",
[
null,
- {}
+ {
+ "testdriver": true
+ }
]
],
"Gyroscope-supported-by-feature-policy.html": [
@@ -599614,10 +600846,11 @@
]
],
"Gyroscope.https.html": [
- "f85349f5315a27bdb06a3b6b4b0fa2c40612a15a",
+ "8aab94693abea6198bb9b7d03c2408cd4bec58a4",
[
null,
{
+ "testdriver": true,
"timeout": "long"
}
]
@@ -599819,6 +601052,13 @@
{}
]
],
+ "raf-coarsened-time.https.html": [
+ "c7cc723da6f4eccc4cb4182da7ee0289537743ae",
+ [
+ null,
+ {}
+ ]
+ ],
"test_cross_frame_start.html": [
"30e804bd7350315497115b75929a52ac1d82d3cb",
[
@@ -602033,6 +603273,33 @@
{}
]
],
+ "pagereveal": {
+ "tentative": {
+ "order-in-bfcache-restore.html": [
+ "f453c80a2aee8c2cff5bca12f361a6a7b7683be8",
+ [
+ null,
+ {
+ "timeout": "long"
+ }
+ ]
+ ],
+ "order-in-new-document-navigation.html": [
+ "d2c44511d3a3a175ceb09298302baec088ddbf76",
+ [
+ null,
+ {}
+ ]
+ ],
+ "order-in-prerender-activation.html": [
+ "b281b2b08810d59c32fe332cb869151946de8c96",
+ [
+ null,
+ {}
+ ]
+ ]
+ }
+ },
"persisted-user-state-restoration": {
"resume-timer-on-history-back.html": [
"77602b2d4258c87a7ac055475986d691da8dad90",
@@ -633306,6 +634573,13 @@
{}
]
],
+ "dir-auto-form-associated.window.js": [
+ "1777f75259bbc1e1bc440c075c06fef00395f797",
+ [
+ "html/dom/elements/global-attributes/dir-auto-form-associated.window.html",
+ {}
+ ]
+ ],
"dir-bdi-script.html": [
"30080430936213b034e09a2cb3fee14608350373",
[
@@ -633355,6 +634629,13 @@
{}
]
],
+ "lang-attribute.window.js": [
+ "de0c03e6f853ecf2b5eac9e41274df49ee96c9e0",
+ [
+ "html/dom/elements/global-attributes/lang-attribute.window.html",
+ {}
+ ]
+ ],
"mapped-attribute-adopt-001.html": [
"66ff3d64f13cdffe4413ee19534604af020203df",
[
@@ -634815,6 +636096,13 @@
{}
]
],
+ "document-base-uri-synthetic-document.html": [
+ "bed090aac42f2ce64ae78ba7fbd24c0bccbb123e",
+ [
+ null,
+ {}
+ ]
+ ],
"document-base-url-changes-about-srcdoc-2.https.html": [
"dab8d2122b64aea58bd9de3d5872a77b307218a8",
[
@@ -642524,6 +643812,13 @@
{}
]
],
+ "img-src-in-synthetic-document.html": [
+ "24c5567fb854bf278033d9287035734e65996d1e",
+ [
+ null,
+ {}
+ ]
+ ],
"img.complete.html": [
"d8d5a84eb7998044fb24847cc0ac5a1185b82bb6",
[
@@ -642909,7 +644204,7 @@
]
],
"dirname-only-if-applies.html": [
- "1fd0476e3140422825d5ec1f7e431b1fc212cbdb",
+ "8af6826fa1359c704368df41c7286520c35d90aa",
[
null,
{}
@@ -644215,6 +645510,15 @@
{}
]
],
+ "input-disabled-fieldset-dynamic.html": [
+ "eefcd972bf1e3c713704c9ff9f2f6f61f0e20b14",
+ [
+ null,
+ {
+ "testdriver": true
+ }
+ ]
+ ],
"input-height.html": [
"dea4f41765284eb65d8c98cebc5782eb58f7f16e",
[
@@ -645694,7 +646998,7 @@
]
],
"dialog-cancel-events.html": [
- "7133ce3ca04ec4c874e93a618ecf0e72065e7fd5",
+ "d583c4cd23c5357b1d358ee6f34bd395bf4c9650",
[
null,
{
@@ -645703,7 +647007,7 @@
]
],
"dialog-cancel-preventDefault.html": [
- "79728b649f4f4a2ca5948b3857678cab762f7927",
+ "4daffc09a46c31205bb22b7b0fe53d5f1302f714",
[
null,
{
@@ -645730,7 +647034,7 @@
]
],
"dialog-canceling.html": [
- "fc003d29d191f5f6ac684a8ce1b6b8acdef07a95",
+ "e368bde6fb30fb59cf5d254c07070c9b177fa892",
[
null,
{
@@ -645898,6 +647202,15 @@
}
]
],
+ "focus-previous-iframe.tentative.html": [
+ "c31daa48766214ffdeae52e03070f22d7b1bf194",
+ [
+ null,
+ {
+ "testdriver": true
+ }
+ ]
+ ],
"inert-does-not-match-disabled-selector.html": [
"b3b0c0a929732da1658487173bf096cc8884c9a7",
[
@@ -646134,7 +647447,7 @@
]
],
"invokeelement-interface.tentative.html": [
- "69cfd80fe56447dc1486134b3bc0b535bf1636c2",
+ "b003daf20d4be5b9eac15b930d10ae2b859ec505",
[
null,
{}
@@ -646150,7 +647463,7 @@
]
],
"invokeevent-interface.tentative.html": [
- "007c97e6fe545a77f2e65cd026720304c24751cf",
+ "82910b3d4418de12453d7ebbee762e3eb9724141",
[
null,
{
@@ -646166,6 +647479,15 @@
"testdriver": true
}
]
+ ],
+ "invoketarget-on-popover-behavior.tentative.html": [
+ "9d9bbaee721edccef6bfca6f0b07f9eec1221227",
+ [
+ null,
+ {
+ "testdriver": true
+ }
+ ]
]
},
"links": {
@@ -646484,6 +647806,15 @@
}
]
],
+ "popover-close-request.html": [
+ "830a40e0608accfdcd4ff07890d78734593de0f7",
+ [
+ null,
+ {
+ "testdriver": true
+ }
+ ]
+ ],
"popover-css-properties.tentative.html": [
"93d388b02b533f8e8719ef8a9b54293f45a5cffd",
[
@@ -646713,7 +648044,7 @@
]
],
"popover-top-layer-combinations.html": [
- "c6fae283874ceadb4c5b8a0ba849a5225c5b8c8f",
+ "024794f57853307e15532e7f1c5ff894a61fa51d",
[
null,
{
@@ -646722,7 +648053,7 @@
]
],
"popover-top-layer-interactions.html": [
- "95da47a5e20df39a4649ed5dad2947285059c1c9",
+ "6d050ed99bb10e26113020dc6f582b7b9a8ada6f",
[
null,
{
@@ -662368,6 +663699,15 @@
}
]
],
+ "loaf-stream-source-location.html": [
+ "3b6b2b31608a915a28eff99f97114b678e341124",
+ [
+ null,
+ {
+ "timeout": "long"
+ }
+ ]
+ ],
"loaf-stream.html": [
"e35bc2f9aa7d7de7a6ac224b9befde30d128e85c",
[
@@ -662650,10 +663990,12 @@
]
],
"Magnetometer-iframe-access.https.html": [
- "3dc90e3dd7f5ac52364f02712ad7083cc373ec6b",
+ "7aabd0eb61b3c7867619169c2da77ca0af128e7c",
[
null,
- {}
+ {
+ "testdriver": true
+ }
]
],
"Magnetometer-supported-by-feature-policy.html": [
@@ -662664,10 +664006,11 @@
]
],
"Magnetometer.https.html": [
- "0cc443784bebb38fce406b7efe934dc10aa7f966",
+ "6beb534509d79f0079d8c4e121020eb529f7a160",
[
null,
{
+ "testdriver": true,
"timeout": "long"
}
]
@@ -665006,7 +666349,7 @@
]
],
"MediaStreamTrack-video-stats.https.html": [
- "6901ed84e39cc081c9bda6f614e0906e71baf47f",
+ "f1b6a2074a4468fca704a8e53a92f25bc13d3200",
[
null,
{
@@ -671630,17 +672973,20 @@
]
],
"AbsoluteOrientationSensor-iframe-access.https.html": [
- "e99b5c6365d3031b24aef5281c31da1f43d2eaa7",
+ "4831b5e719200d34903d2d20dce2675a70e3a3e5",
[
null,
- {}
+ {
+ "testdriver": true
+ }
]
],
"AbsoluteOrientationSensor.https.html": [
- "e6f5dd913835a99ef2a1fce328041ad527b54da5",
+ "4c516da145169e29d0a1f5bbd1bf326404b722d5",
[
null,
{
+ "testdriver": true,
"timeout": "long"
}
]
@@ -671688,17 +673034,20 @@
]
],
"RelativeOrientationSensor-iframe-access.https.html": [
- "5d30534841bfc45573a5720f411636533a37cb65",
+ "fe995e2d1b982db7dff6729da7e5148487d8fbd7",
[
null,
- {}
+ {
+ "testdriver": true
+ }
]
],
"RelativeOrientationSensor.https.html": [
- "499e7df8ceac2408092972bcaa2f4c4b14a0bf82",
+ "35dc8c3111363721c0f6645778b1cd96ec1a6483",
[
null,
{
+ "testdriver": true,
"timeout": "long"
}
]
@@ -675566,7 +676915,7 @@
]
],
"pointerevent_after_target_removed.html": [
- "5ab6040cc9ce1b4cb9ad6581c8aa29d3be715e7e",
+ "2dcc94c2b2321be2523d43e698d5c470373a24f6",
[
"pointerevents/pointerevent_after_target_removed.html?mouse",
{
@@ -690344,7 +691693,7 @@
]
],
"callback-timeRemaining-cross-realm-method.html": [
- "383479d64a093709e4ffbf7b75a8a3f776ef8cd3",
+ "078e2c9379c8629dd971ad2fe3577d48890130c7",
[
null,
{
@@ -704705,7 +706054,7 @@
]
},
"estimate-indexeddb.https.any.js": [
- "f0b82b9fa09fb1ef7000e398fb0fdb034504a008",
+ "6577b021ad52ef36ab8748102ec760dfd0f44205",
[
"storage/estimate-indexeddb.https.any.html",
{
@@ -705003,7 +706352,7 @@
]
],
"storagemanager-estimate.https.any.js": [
- "c2f5c569dc528cb8e58e8c057ba95ce1354463a7",
+ "3b6f4d8edc4c2e51d6e9efbc2a2929e75d6b6725",
[
"storage/storagemanager-estimate.https.any.html",
{
@@ -705283,6 +706632,32 @@
}
]
],
+ "requestStorageAccess-dedicated-worker.tentative.sub.https.window.js": [
+ "86caf8191828712fc02733a55c87d54022c97d8c",
+ [
+ "storage-access-api/requestStorageAccess-dedicated-worker.tentative.sub.https.window.html",
+ {
+ "script_metadata": [
+ [
+ "script",
+ "helpers.js"
+ ],
+ [
+ "script",
+ "/cookies/resources/cookie-helper.sub.js"
+ ],
+ [
+ "script",
+ "/resources/testdriver.js"
+ ],
+ [
+ "script",
+ "/resources/testdriver-vendor.js"
+ ]
+ ]
+ }
+ ]
+ ],
"requestStorageAccess-insecure.sub.window.js": [
"1ad04321db7f4ce9e55d8676fecee8fd6604c8ca",
[
@@ -705448,6 +706823,78 @@
{}
]
],
+ "storage-access-beyond-cookies.indexedDB.tentative.sub.https.window.js": [
+ "18c4317bbe9c6598551787feaf9df9d4ad5210db",
+ [
+ "storage-access-api/storage-access-beyond-cookies.indexedDB.tentative.sub.https.window.html",
+ {
+ "script_metadata": [
+ [
+ "script",
+ "/resources/testdriver.js"
+ ],
+ [
+ "script",
+ "/resources/testdriver-vendor.js"
+ ]
+ ]
+ }
+ ]
+ ],
+ "storage-access-beyond-cookies.localStorage.tentative.sub.https.window.js": [
+ "108e778766db5d89fb442ceb4d6ab37cf50aee38",
+ [
+ "storage-access-api/storage-access-beyond-cookies.localStorage.tentative.sub.https.window.html",
+ {
+ "script_metadata": [
+ [
+ "script",
+ "/resources/testdriver.js"
+ ],
+ [
+ "script",
+ "/resources/testdriver-vendor.js"
+ ]
+ ]
+ }
+ ]
+ ],
+ "storage-access-beyond-cookies.locks.tentative.sub.https.window.js": [
+ "83aa28c018e1a3e4fd0b5ffe794a2acb751de287",
+ [
+ "storage-access-api/storage-access-beyond-cookies.locks.tentative.sub.https.window.html",
+ {
+ "script_metadata": [
+ [
+ "script",
+ "/resources/testdriver.js"
+ ],
+ [
+ "script",
+ "/resources/testdriver-vendor.js"
+ ]
+ ]
+ }
+ ]
+ ],
+ "storage-access-beyond-cookies.sessionStorage.tentative.sub.https.window.js": [
+ "2e504851c22b58c60e79829f7bd9921424a877df",
+ [
+ "storage-access-api/storage-access-beyond-cookies.sessionStorage.tentative.sub.https.window.html",
+ {
+ "script_metadata": [
+ [
+ "script",
+ "/resources/testdriver.js"
+ ],
+ [
+ "script",
+ "/resources/testdriver-vendor.js"
+ ]
+ ]
+ }
+ ]
+ ],
"storage-access-permission.sub.https.window.js": [
"f0aadf4828dcb549c0d66ef4745b1e190d56f8d6",
[
@@ -719784,7 +721231,7 @@
]
],
"invalid-roles.html": [
- "e16fb677044df6a283b2a34df9b6c0de2c2d89a1",
+ "3f4255083e1adf05202cad3a4ae8d4a58b7f5e07",
[
null,
{
@@ -720329,7 +721776,7 @@
},
"exception": {
"basic.tentative.any.js": [
- "869c64b6d303daed40c16e38bf68ee2dd559529d",
+ "cacce99d9cb227055754554b8369809c92885ded",
[
null,
{
@@ -721024,6 +722471,155 @@
]
]
},
+ "gc": {
+ "casts.tentative.any.js": [
+ "cce06224fd40c70f037dbf575388c26106480a0e",
+ [
+ null,
+ {
+ "jsshell": true,
+ "script_metadata": [
+ [
+ "global",
+ "window,dedicatedworker,jsshell"
+ ],
+ [
+ "script",
+ "/wasm/jsapi/wasm-module-builder.js"
+ ]
+ ]
+ }
+ ],
+ [
+ "wasm/jsapi/gc/casts.tentative.any.html",
+ {
+ "script_metadata": [
+ [
+ "global",
+ "window,dedicatedworker,jsshell"
+ ],
+ [
+ "script",
+ "/wasm/jsapi/wasm-module-builder.js"
+ ]
+ ]
+ }
+ ],
+ [
+ "wasm/jsapi/gc/casts.tentative.any.worker.html",
+ {
+ "script_metadata": [
+ [
+ "global",
+ "window,dedicatedworker,jsshell"
+ ],
+ [
+ "script",
+ "/wasm/jsapi/wasm-module-builder.js"
+ ]
+ ]
+ }
+ ]
+ ],
+ "exported-object.tentative.any.js": [
+ "b572f140067fda658eb18ab82c880b3697172aba",
+ [
+ null,
+ {
+ "jsshell": true,
+ "script_metadata": [
+ [
+ "global",
+ "window,dedicatedworker,jsshell"
+ ],
+ [
+ "script",
+ "/wasm/jsapi/wasm-module-builder.js"
+ ]
+ ]
+ }
+ ],
+ [
+ "wasm/jsapi/gc/exported-object.tentative.any.html",
+ {
+ "script_metadata": [
+ [
+ "global",
+ "window,dedicatedworker,jsshell"
+ ],
+ [
+ "script",
+ "/wasm/jsapi/wasm-module-builder.js"
+ ]
+ ]
+ }
+ ],
+ [
+ "wasm/jsapi/gc/exported-object.tentative.any.worker.html",
+ {
+ "script_metadata": [
+ [
+ "global",
+ "window,dedicatedworker,jsshell"
+ ],
+ [
+ "script",
+ "/wasm/jsapi/wasm-module-builder.js"
+ ]
+ ]
+ }
+ ]
+ ],
+ "i31.tentative.any.js": [
+ "17fd82440cc8b29c6826d32e46f52b5c2a0323a1",
+ [
+ null,
+ {
+ "jsshell": true,
+ "script_metadata": [
+ [
+ "global",
+ "window,dedicatedworker,jsshell"
+ ],
+ [
+ "script",
+ "/wasm/jsapi/wasm-module-builder.js"
+ ]
+ ]
+ }
+ ],
+ [
+ "wasm/jsapi/gc/i31.tentative.any.html",
+ {
+ "script_metadata": [
+ [
+ "global",
+ "window,dedicatedworker,jsshell"
+ ],
+ [
+ "script",
+ "/wasm/jsapi/wasm-module-builder.js"
+ ]
+ ]
+ }
+ ],
+ [
+ "wasm/jsapi/gc/i31.tentative.any.worker.html",
+ {
+ "script_metadata": [
+ [
+ "global",
+ "window,dedicatedworker,jsshell"
+ ],
+ [
+ "script",
+ "/wasm/jsapi/wasm-module-builder.js"
+ ]
+ ]
+ }
+ ]
+ ]
+ },
"global": {
"constructor.any.js": [
"f83f77a5c3ecf349ea63891f4ebcfc2109ae2606",
@@ -722363,7 +723959,7 @@
]
],
"exports.any.js": [
- "499a2649b171739cfcee1087f9779b30bcde08bd",
+ "0c32e984a2cad1feba8dc949ae4a83f84a9db45e",
[
null,
{
@@ -724413,6 +726009,13 @@
{}
]
],
+ "scrollbar-interpolation.html": [
+ "bc02dd00b97ba84f55e132069833f16827164525",
+ [
+ null,
+ {}
+ ]
+ ],
"visibility.html": [
"f5a60b4e2c7bb3c70a45353c7734dd0dff51d780",
[
@@ -727510,11 +729113,22 @@
{}
]
],
- "audioparam-default-value.html": [
- "fe0cf15b43d38ad271a2b62105810de45b4e8791",
+ "audioparam-default-value.window.js": [
+ "359df111846403c1ba9038792dabd6e8989f9d96",
[
- null,
- {}
+ "webaudio/the-audio-api/the-audioparam-interface/audioparam-default-value.window.html",
+ {
+ "script_metadata": [
+ [
+ "script",
+ "/resources/testharness.js"
+ ],
+ [
+ "script",
+ "/resources/testharnessreport.js"
+ ]
+ ]
+ }
]
],
"audioparam-exceptional-values.html": [
@@ -729239,6 +730853,16 @@
{}
]
],
+ "storecredential.https.html": [
+ "726b289fbd18e8bd7646f2d6ad0b88b718c16293",
+ [
+ null,
+ {
+ "testdriver": true,
+ "timeout": "long"
+ }
+ ]
+ ],
"webauthn-testdriver-basic.https.html": [
"5751928301ff6c75593881f6e0bb0c5f93076d8c",
[
@@ -729369,7 +730993,7 @@
]
],
"audio-decoder.https.any.js": [
- "606b052edc891ec023c832b9e7f877e835b375cc",
+ "79ba22157abba6dcc890fd72b3328bdd0b7f7093",
[
"webcodecs/audio-decoder.https.any.html",
{
@@ -729420,7 +731044,7 @@
]
],
"audio-encoder-config.https.any.js": [
- "98a9513b7dc301adce0e351307f0f7859f7f104c",
+ "3be8eb3f6d36d270808ca0a418387fc83245ea12",
[
"webcodecs/audio-encoder-config.https.any.html",
{
@@ -731935,7 +733559,7 @@
]
],
"video-decoder.https.any.js": [
- "190a524dd6c75fdcb7675e936ee4f8813202d4a6",
+ "77a610bd4ea2ca090ba029cdf1239e83184873b8",
[
"webcodecs/video-decoder.https.any.html",
{
@@ -731968,7 +733592,7 @@
]
],
"video-encoder-config.https.any.js": [
- "e4807361fcaa4ed9de459deb4f441c4cf2f9be40",
+ "5011bfdd0a8506f3c236d3cdaf197458f5cc9a45",
[
"webcodecs/video-encoder-config.https.any.html",
{
@@ -751976,11 +753600,83 @@
}
]
],
- "echo-large-bidirectional-streams.https.html": [
- "daa7c1b9b367890c9e29f0419648329f42a15eb9",
+ "echo-large-bidirectional-streams.https.any.js": [
+ "3f46530327eea602c781a60a524b8c5cf5094e87",
[
- null,
- {}
+ "webtransport/echo-large-bidirectional-streams.https.any.html",
+ {
+ "script_metadata": [
+ [
+ "global",
+ "window,worker"
+ ],
+ [
+ "script",
+ "/common/get-host-info.sub.js"
+ ],
+ [
+ "script",
+ "resources/webtransport-test-helpers.sub.js"
+ ]
+ ]
+ }
+ ],
+ [
+ "webtransport/echo-large-bidirectional-streams.https.any.serviceworker.html",
+ {
+ "script_metadata": [
+ [
+ "global",
+ "window,worker"
+ ],
+ [
+ "script",
+ "/common/get-host-info.sub.js"
+ ],
+ [
+ "script",
+ "resources/webtransport-test-helpers.sub.js"
+ ]
+ ]
+ }
+ ],
+ [
+ "webtransport/echo-large-bidirectional-streams.https.any.sharedworker.html",
+ {
+ "script_metadata": [
+ [
+ "global",
+ "window,worker"
+ ],
+ [
+ "script",
+ "/common/get-host-info.sub.js"
+ ],
+ [
+ "script",
+ "resources/webtransport-test-helpers.sub.js"
+ ]
+ ]
+ }
+ ],
+ [
+ "webtransport/echo-large-bidirectional-streams.https.any.worker.html",
+ {
+ "script_metadata": [
+ [
+ "global",
+ "window,worker"
+ ],
+ [
+ "script",
+ "/common/get-host-info.sub.js"
+ ],
+ [
+ "script",
+ "resources/webtransport-test-helpers.sub.js"
+ ]
+ ]
+ }
]
],
"idlharness.https.any.js": [
@@ -783246,6 +784942,15 @@
]
]
},
+ "context_destroyed": {
+ "context_destroyed.py": [
+ "5baac7abd2d4f35dc1ee753973926d7697309a31",
+ [
+ null,
+ {}
+ ]
+ ]
+ },
"create": {
"background.py": [
"f1effe05372af81564c605a2a243a5737c481a75",
@@ -783558,7 +785263,7 @@
},
"user_prompt_opened": {
"user_prompt_opened.py": [
- "a24a1e86abab3dd562b96f3951b7ca0836990012",
+ "a2d5d840a496bd3b6ab49283c36a49629a83d105",
[
null,
{}
@@ -784008,7 +785713,7 @@
]
],
"result_node.py": [
- "9d09b9fc04ace5d463976ee1a0af6d6b163e9b72",
+ "47cbd42d22d00355bbed097c509d8e0d409d5145",
[
null,
{}
@@ -784059,7 +785764,7 @@
},
"classic_interop": {
"node_shared_id.py": [
- "82b39b42e1c64dad4e4c8a772b5e893f75713ef9",
+ "aeb2bc45978829877dbc554bc580151a341c5d44",
[
null,
{}
@@ -784161,7 +785866,7 @@
]
],
"result_node.py": [
- "a3ca316d0275f566e4bc913beae24ffae58af36d",
+ "a0bfd0d4c0215b8a0b7fb8ba0276759c966af977",
[
null,
{}
@@ -784471,7 +786176,7 @@
},
"element_clear": {
"clear.py": [
- "9b0d7f2133f7686603449897c659c7e4220ec746",
+ "22c07b6a8ce241a7166511c539765f1cd959edcb",
[
null,
{
@@ -784505,14 +786210,14 @@
]
],
"click.py": [
- "3c3f7d70e6c6b23932e7452f73e160a2d213a5ba",
+ "61acc923e8eb3f6883d09bb4bfa220d7f757bbb8",
[
null,
{}
]
],
"events.py": [
- "30f2dfa0a4a9b5f643832d751f0b35ecfff89fc2",
+ "5e80b52e879c6c8383d47322cc090dfb3b2304b3",
[
null,
{}
@@ -784614,7 +786319,7 @@
]
],
"send_keys.py": [
- "281c7ad719ddd05dac2ab7c6de343e9bebde4a5b",
+ "92002f294576b9108d29d5bbf39a13a248094e8d",
[
null,
{}
@@ -784632,7 +786337,7 @@
},
"execute_async_script": {
"arguments.py": [
- "ead6e0c186ea40771643aea56ccc7180e6cc28d7",
+ "81b30de26786a2620638e45f6648440bbfa17595",
[
null,
{}
@@ -784653,14 +786358,14 @@
]
],
"execute_async.py": [
- "42cf4aacee8342939c515b5e56a40ef15a1cacfb",
+ "3c8cc6210d4b1a6a51c4b465f86e20001cb889b5",
[
null,
{}
]
],
"node.py": [
- "53abda4b300597ade2f5b8d38260caad9cb17f31",
+ "2f1bf75e83c0e93020cdc16e8247e78bbccb44ff",
[
null,
{}
@@ -784695,11 +786400,18 @@
"timeout": "long"
}
]
+ ],
+ "window.py": [
+ "f79bfdf49d9832c79a073de8709e626adf00770a",
+ [
+ null,
+ {}
+ ]
]
},
"execute_script": {
"arguments.py": [
- "b8657ce0efae2a266158bb8c2846864cd63c1d5e",
+ "ab5c5234ba143c707d1b4ef97a1212cc99702fb0",
[
null,
{}
@@ -784720,21 +786432,14 @@
]
],
"execute.py": [
- "fbccc98633867b9ab137b26f0f8818b98a29c81f",
- [
- null,
- {}
- ]
- ],
- "json_serialize_windowproxy.py": [
- "8e76feda23809bf65a77c6bcd3994209aaba40e0",
+ "15ac1d0132a224ff836e38681733697a33dcc0ae",
[
null,
{}
]
],
"node.py": [
- "caf85988f15413eca765c5d5cb019b06777d3b9d",
+ "61cf3463dcbbd454a6aad1cae40136a5aaa4432f",
[
null,
{}
@@ -784769,6 +786474,13 @@
"timeout": "long"
}
]
+ ],
+ "window.py": [
+ "9ab45d7cb780389e7cc071ba0ae49c9ae3e2259e",
+ [
+ null,
+ {}
+ ]
]
},
"find_element": {
@@ -784809,7 +786521,7 @@
},
"find_element_from_shadow_root": {
"find.py": [
- "3f1b64a61c5bd336af86613eb7ce091b2bcecee7",
+ "c658152ee6910d9d00eaa4f843a3d60719787776",
[
null,
{}
@@ -784863,7 +786575,7 @@
},
"find_elements_from_shadow_root": {
"find.py": [
- "ffdaa7e84b05ead748b2f61e2bfc344652f65244",
+ "188fff29212efdafb123aa0ba0a578b5ab15dd77",
[
null,
{}
@@ -784953,7 +786665,7 @@
},
"get_computed_label": {
"get.py": [
- "0dc00a471a9a37509e4ed7a448c1213bb978eeda",
+ "e023b79cea52226e85fdd601a4516bd73cf8d936",
[
null,
{}
@@ -784962,7 +786674,7 @@
},
"get_computed_role": {
"get.py": [
- "51b6a8b3b6d1e302be8885e4b2976cc0c02ff4bd",
+ "1b8489675cea5a8c6c4183fc1bd989332e6cc308",
[
null,
{}
@@ -785003,7 +786715,7 @@
},
"get_element_attribute": {
"get.py": [
- "375f25032c06a10fecf78a884647056fbd826b9d",
+ "0fcfd00c97c5e9abe44dd39cc2ed7e04dbe785c3",
[
null,
{}
@@ -785021,7 +786733,7 @@
},
"get_element_css_value": {
"get.py": [
- "6f0a8a56395788be0f9152028f569f133fcd79ed",
+ "1f6f571149bd259a7b49393b6ef39ad31b843295",
[
null,
{}
@@ -785039,7 +786751,7 @@
},
"get_element_property": {
"get.py": [
- "bb63481dfcae75ee6f80503413c552db78d3c8ac",
+ "12d48a3abb5ae334219bf4103d5a693e5eed13ad",
[
null,
{}
@@ -785057,7 +786769,7 @@
},
"get_element_rect": {
"get.py": [
- "942f119f43c9bb30eaefd52f3c793d7e47cfbfc4",
+ "959ccc455ecdbd476874d546139816cc2955c7d8",
[
null,
{}
@@ -785075,7 +786787,7 @@
},
"get_element_shadow_root": {
"get.py": [
- "d9adde0b9e3aee402aa2e03db9d02259d968e81b",
+ "25e68c1bbac2e3cd041fd76af64cb9a24c754e20",
[
null,
{}
@@ -785093,7 +786805,7 @@
},
"get_element_tag_name": {
"get.py": [
- "3bb03d79886d88c6ba045d9f0bedae7414412025",
+ "d8bb3acc500b5aeb1c3a97c7c912e8f3ea5cbe3a",
[
null,
{}
@@ -785111,7 +786823,7 @@
},
"get_element_text": {
"get.py": [
- "e8d559cf661acee18a39cbc4b6bb03289385ca08",
+ "2a2363c0528eefa90981289ff608dd880ece4226",
[
null,
{}
@@ -785262,7 +786974,7 @@
},
"is_element_enabled": {
"enabled.py": [
- "fccff383a55a7929179810216407acbdea0a079c",
+ "24fc85fdad2daba04b6770c536d0ae4de9ee95bb",
[
null,
{}
@@ -785280,7 +786992,7 @@
},
"is_element_selected": {
"selected.py": [
- "1fb5b9ce86b521069f638956272e3101ea62cc5c",
+ "bf650de3e23b5ab5f04d7704f8c34e9edbbb4d47",
[
null,
{}
@@ -785579,7 +787291,7 @@
]
],
"pointer_mouse.py": [
- "97295f56f41324dc19925b2ea5109815a8c89a78",
+ "6ccb7c404e0e803e20bb7be532f45b248bd9d455",
[
null,
{
@@ -785851,7 +787563,7 @@
]
],
"screenshot.py": [
- "ea4cc290db4cdd603d9dc20bbc90914c4e241cb5",
+ "fdc0d65b1d9c515701147f88261c41d37deee8b9",
[
null,
{}
diff --git a/tests/wpt/meta/css/CSS2/linebox/inline-negative-margin-001.html.ini b/tests/wpt/meta/css/CSS2/linebox/inline-negative-margin-001.html.ini
index ba1ea35fa63..66a6e016faa 100644
--- a/tests/wpt/meta/css/CSS2/linebox/inline-negative-margin-001.html.ini
+++ b/tests/wpt/meta/css/CSS2/linebox/inline-negative-margin-001.html.ini
@@ -2,21 +2,6 @@
[[data-expected-height\] 7]
expected: FAIL
- [[data-expected-height\] 9]
- expected: FAIL
-
- [[data-expected-height\] 10]
- expected: FAIL
-
- [[data-expected-height\] 11]
- expected: FAIL
-
- [[data-expected-height\] 12]
- expected: FAIL
-
- [[data-expected-height\] 13]
- expected: FAIL
-
[[data-expected-height\] 3]
expected: FAIL
diff --git a/tests/wpt/meta/css/css-color/system-color-support.html.ini b/tests/wpt/meta/css/css-color/system-color-support.html.ini
new file mode 100644
index 00000000000..28563ddd87a
--- /dev/null
+++ b/tests/wpt/meta/css/css-color/system-color-support.html.ini
@@ -0,0 +1,57 @@
+[system-color-support.html]
+ [System color Canvas works]
+ expected: FAIL
+
+ [System color CanvasText works]
+ expected: FAIL
+
+ [System color LinkText works]
+ expected: FAIL
+
+ [System color VisitedText works]
+ expected: FAIL
+
+ [System color ActiveText works]
+ expected: FAIL
+
+ [System color ButtonFace works]
+ expected: FAIL
+
+ [System color ButtonText works]
+ expected: FAIL
+
+ [System color ButtonBorder works]
+ expected: FAIL
+
+ [System color Field works]
+ expected: FAIL
+
+ [System color FieldText works]
+ expected: FAIL
+
+ [System color Highlight works]
+ expected: FAIL
+
+ [System color HighlightText works]
+ expected: FAIL
+
+ [System color SelectedItem works]
+ expected: FAIL
+
+ [System color SelectedItemText works]
+ expected: FAIL
+
+ [System color Mark works]
+ expected: FAIL
+
+ [System color MarkText works]
+ expected: FAIL
+
+ [System color GrayText works]
+ expected: FAIL
+
+ [System color AccentColor works]
+ expected: FAIL
+
+ [System color AccentColorText works]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-fonts/animations/font-palette-animation-not-specified-endpoints.html.ini b/tests/wpt/meta/css/css-fonts/animations/font-palette-animation-not-specified-endpoints.html.ini
new file mode 100644
index 00000000000..48224fe6767
--- /dev/null
+++ b/tests/wpt/meta/css/css-fonts/animations/font-palette-animation-not-specified-endpoints.html.ini
@@ -0,0 +1,7 @@
+[font-palette-animation-not-specified-endpoints.html]
+ expected: TIMEOUT
+ [Verify font-palette is animated when `from` keyframe is not specified]
+ expected: NOTRUN
+
+ [Verify font-palette is animated when `to` keyframe is not specified]
+ expected: NOTRUN
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 02f4760ad1c..1ba53e3a2fc 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
@@ -20,9 +20,6 @@
[Matching font-weight: '430' should prefer '420 440' over '450 460']
expected: FAIL
- [Matching font-weight: '430' should prefer '350 399' over '340 398']
- expected: FAIL
-
[Matching font-weight: '430' should prefer '501 550' over '502 560']
expected: FAIL
@@ -56,9 +53,6 @@
[Matching font-style: 'oblique 20deg' should prefer 'oblique -50deg -20deg' over 'oblique -40deg -30deg']
expected: FAIL
- [Matching font-style: 'oblique 10deg' should prefer 'italic' over 'oblique 0deg']
- expected: FAIL
-
[Matching font-style: 'oblique 10deg' should prefer 'oblique -50deg -20deg' over 'oblique -40deg -30deg']
expected: FAIL
@@ -83,9 +77,6 @@
[Matching font-style: 'oblique -10deg' should prefer 'oblique 0deg 10deg' over 'oblique 40deg 50deg']
expected: FAIL
- [Matching font-style: 'oblique -20deg' should prefer 'oblique 0deg' over 'oblique 30deg 60deg']
- expected: FAIL
-
[Matching font-style: 'oblique 21deg' should prefer 'oblique 40deg 50deg' over 'oblique 20deg']
expected: FAIL
@@ -149,9 +140,6 @@
[Matching font-style: 'oblique 21deg' should prefer 'oblique 30deg 60deg' over 'oblique 40deg 50deg']
expected: FAIL
- [Matching font-style: 'oblique -21deg' should prefer 'oblique 30deg 60deg' over 'oblique 40deg 50deg']
- expected: FAIL
-
[Matching font-style: 'oblique 21deg' should prefer 'oblique -50deg -20deg' over 'oblique -40deg -30deg']
expected: FAIL
@@ -161,9 +149,6 @@
[Matching font-style: 'oblique -20deg' should prefer 'italic' over 'oblique 0deg']
expected: FAIL
- [Matching font-style: 'normal' should prefer 'oblique 20deg 30deg' over 'oblique -50deg -20deg']
- expected: FAIL
-
[Matching font-style: 'italic' should prefer 'oblique -60deg -30deg' over 'oblique -50deg -40deg']
expected: FAIL
@@ -185,9 +170,6 @@
[Matching font-weight: '430' should prefer '450 460' over '500']
expected: FAIL
- [Matching font-style: 'italic' should prefer 'italic' over 'oblique 20deg']
- expected: FAIL
-
[Matching font-stretch: '100%' should prefer '100%' over '110% 120%']
expected: FAIL
@@ -265,3 +247,51 @@
[Matching font-style: 'oblique -21deg' should prefer 'oblique -60deg -40deg' over 'oblique -10deg']
expected: FAIL
+
+ [Matching font-weight: '400' should prefer '501 550' over '502 560']
+ expected: FAIL
+
+ [Matching font-weight: '501' should prefer '501' over '502 510']
+ expected: FAIL
+
+ [Matching font-stretch: '100%' should prefer '110% 120%' over '115% 116%']
+ expected: FAIL
+
+ [Matching font-stretch: '110%' should prefer '110% 120%' over '115% 116%']
+ expected: FAIL
+
+ [Matching font-style: 'normal' should prefer 'normal' over 'oblique 0deg']
+ expected: FAIL
+
+ [Matching font-style: 'normal' should prefer 'oblique -50deg -20deg' over 'oblique -40deg -30deg']
+ expected: FAIL
+
+ [Matching font-style: 'italic' should prefer 'oblique 40deg 50deg' over 'oblique 5deg 10deg']
+ expected: FAIL
+
+ [Matching font-style: 'italic' should prefer 'normal' over 'oblique 0deg']
+ expected: FAIL
+
+ [Matching font-style: 'oblique 20deg' should prefer 'oblique 10deg' over 'italic']
+ expected: FAIL
+
+ [Matching font-style: 'oblique 20deg' should prefer 'italic' over 'oblique 0deg']
+ expected: FAIL
+
+ [Matching font-style: 'oblique 21deg' should prefer 'italic' over 'oblique 0deg']
+ expected: FAIL
+
+ [Matching font-style: 'oblique 10deg' should prefer 'oblique 10deg' over 'oblique 5deg']
+ expected: FAIL
+
+ [Matching font-style: 'oblique 10deg' should prefer 'oblique 5deg' over 'oblique 15deg 20deg']
+ expected: FAIL
+
+ [Matching font-style: 'oblique 0deg' should prefer 'oblique 0deg' over 'oblique 5deg']
+ expected: FAIL
+
+ [Matching font-style: 'oblique 0deg' should prefer 'oblique 5deg' over 'oblique 15deg 20deg']
+ expected: FAIL
+
+ [Matching font-style: 'oblique -21deg' should prefer 'oblique 0deg' over 'oblique 30deg 60deg']
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-images/parsing/gradient-interpolation-method-computed.html.ini b/tests/wpt/meta/css/css-images/parsing/gradient-interpolation-method-computed.html.ini
index ac3cd32db81..9e15d59a455 100644
--- a/tests/wpt/meta/css/css-images/parsing/gradient-interpolation-method-computed.html.ini
+++ b/tests/wpt/meta/css/css-images/parsing/gradient-interpolation-method-computed.html.ini
@@ -815,12 +815,6 @@
[Property background-image value 'linear-gradient(in oklch decreasing hue to right bottom, color(srgb 1 0 0), blue)']
expected: FAIL
- [Property background-image value 'radial-gradient(ellipse 50% 40em, red, blue)']
- expected: FAIL
-
- [Property background-image value 'radial-gradient(at right center, red, blue)']
- expected: FAIL
-
[Property background-image value 'radial-gradient(50px, color(srgb 1 0 0), blue)']
expected: FAIL
diff --git a/tests/wpt/meta/css/css-text/inheritance.html.ini b/tests/wpt/meta/css/css-text/inheritance.html.ini
index a8eba1c02e2..fe48e832022 100644
--- a/tests/wpt/meta/css/css-text/inheritance.html.ini
+++ b/tests/wpt/meta/css/css-text/inheritance.html.ini
@@ -76,3 +76,15 @@
[Property white-space-collapse inherits]
expected: FAIL
+
+ [Property text-wrap-mode has initial value wrap]
+ expected: FAIL
+
+ [Property text-wrap-mode inherits]
+ expected: FAIL
+
+ [Property text-wrap-style has initial value auto]
+ expected: FAIL
+
+ [Property text-wrap-style inherits]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-text/parsing/text-wrap-computed.html.ini b/tests/wpt/meta/css/css-text/parsing/text-wrap-computed.html.ini
new file mode 100644
index 00000000000..dbe3756bbab
--- /dev/null
+++ b/tests/wpt/meta/css/css-text/parsing/text-wrap-computed.html.ini
@@ -0,0 +1,66 @@
+[text-wrap-computed.html]
+ [Property text-wrap value 'wrap']
+ expected: FAIL
+
+ [Property text-wrap value 'nowrap']
+ expected: FAIL
+
+ [Property text-wrap value 'auto']
+ expected: FAIL
+
+ [Property text-wrap value 'balance']
+ expected: FAIL
+
+ [Property text-wrap value 'stable']
+ expected: FAIL
+
+ [Property text-wrap value 'pretty']
+ expected: FAIL
+
+ [Property text-wrap value 'wrap auto']
+ expected: FAIL
+
+ [Property text-wrap value 'wrap balance']
+ expected: FAIL
+
+ [Property text-wrap value 'wrap pretty']
+ expected: FAIL
+
+ [Property text-wrap value 'wrap stable']
+ expected: FAIL
+
+ [Property text-wrap value 'auto wrap']
+ expected: FAIL
+
+ [Property text-wrap value 'balance wrap']
+ expected: FAIL
+
+ [Property text-wrap value 'pretty wrap']
+ expected: FAIL
+
+ [Property text-wrap value 'stable wrap']
+ expected: FAIL
+
+ [Property text-wrap value 'nowrap auto']
+ expected: FAIL
+
+ [Property text-wrap value 'nowrap balance']
+ expected: FAIL
+
+ [Property text-wrap value 'nowrap pretty']
+ expected: FAIL
+
+ [Property text-wrap value 'nowrap stable']
+ expected: FAIL
+
+ [Property text-wrap value 'auto nowrap']
+ expected: FAIL
+
+ [Property text-wrap value 'balance nowrap']
+ expected: FAIL
+
+ [Property text-wrap value 'pretty nowrap']
+ expected: FAIL
+
+ [Property text-wrap value 'stable nowrap']
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-text/parsing/text-wrap-mode-computed.html.ini b/tests/wpt/meta/css/css-text/parsing/text-wrap-mode-computed.html.ini
new file mode 100644
index 00000000000..f9739ca0b28
--- /dev/null
+++ b/tests/wpt/meta/css/css-text/parsing/text-wrap-mode-computed.html.ini
@@ -0,0 +1,6 @@
+[text-wrap-mode-computed.html]
+ [Property text-wrap-mode value 'wrap']
+ expected: FAIL
+
+ [Property text-wrap-mode value 'nowrap']
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-text/parsing/text-wrap-mode-valid.html.ini b/tests/wpt/meta/css/css-text/parsing/text-wrap-mode-valid.html.ini
new file mode 100644
index 00000000000..76dc7a87b4e
--- /dev/null
+++ b/tests/wpt/meta/css/css-text/parsing/text-wrap-mode-valid.html.ini
@@ -0,0 +1,21 @@
+[text-wrap-mode-valid.html]
+ [e.style['text-wrap-mode'\] = "wrap" should set the property value]
+ expected: FAIL
+
+ [e.style['text-wrap-mode'\] = "nowrap" should set the property value]
+ expected: FAIL
+
+ [e.style['text-wrap-mode'\] = "initial" should set the property value]
+ expected: FAIL
+
+ [e.style['text-wrap-mode'\] = "inherit" should set the property value]
+ expected: FAIL
+
+ [e.style['text-wrap-mode'\] = "unset" should set the property value]
+ expected: FAIL
+
+ [e.style['text-wrap-mode'\] = "revert" should set the property value]
+ expected: FAIL
+
+ [e.style['text-wrap-mode'\] = "revert-layer" should set the property value]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-text/parsing/text-wrap-style-computed.html.ini b/tests/wpt/meta/css/css-text/parsing/text-wrap-style-computed.html.ini
new file mode 100644
index 00000000000..8be1df9f7ff
--- /dev/null
+++ b/tests/wpt/meta/css/css-text/parsing/text-wrap-style-computed.html.ini
@@ -0,0 +1,12 @@
+[text-wrap-style-computed.html]
+ [Property text-wrap-style value 'auto']
+ expected: FAIL
+
+ [Property text-wrap-style value 'balance']
+ expected: FAIL
+
+ [Property text-wrap-style value 'pretty']
+ expected: FAIL
+
+ [Property text-wrap-style value 'stable']
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-text/parsing/text-wrap-style-valid.html.ini b/tests/wpt/meta/css/css-text/parsing/text-wrap-style-valid.html.ini
new file mode 100644
index 00000000000..fd637df85db
--- /dev/null
+++ b/tests/wpt/meta/css/css-text/parsing/text-wrap-style-valid.html.ini
@@ -0,0 +1,27 @@
+[text-wrap-style-valid.html]
+ [e.style['text-wrap-style'\] = "auto" should set the property value]
+ expected: FAIL
+
+ [e.style['text-wrap-style'\] = "balance" should set the property value]
+ expected: FAIL
+
+ [e.style['text-wrap-style'\] = "pretty" should set the property value]
+ expected: FAIL
+
+ [e.style['text-wrap-style'\] = "stable" should set the property value]
+ expected: FAIL
+
+ [e.style['text-wrap-style'\] = "initial" should set the property value]
+ expected: FAIL
+
+ [e.style['text-wrap-style'\] = "inherit" should set the property value]
+ expected: FAIL
+
+ [e.style['text-wrap-style'\] = "unset" should set the property value]
+ expected: FAIL
+
+ [e.style['text-wrap-style'\] = "revert" should set the property value]
+ expected: FAIL
+
+ [e.style['text-wrap-style'\] = "revert-layer" should set the property value]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-values/round-mod-rem-computed.html.ini b/tests/wpt/meta/css/css-values/round-mod-rem-computed.html.ini
index d611c6fdc4c..25cc0592b87 100644
--- a/tests/wpt/meta/css/css-values/round-mod-rem-computed.html.ini
+++ b/tests/wpt/meta/css/css-values/round-mod-rem-computed.html.ini
@@ -700,3 +700,12 @@
[mod(4, -Infinity) should be used-value-equivalent to calc(NaN)]
expected: FAIL
+
+ [round(1px + 0%, 1px) should be used-value-equivalent to 1px]
+ expected: FAIL
+
+ [mod(3px + 0%, 2px) should be used-value-equivalent to 1px]
+ expected: FAIL
+
+ [rem(3px + 0%, 2px) should be used-value-equivalent to 1px]
+ expected: FAIL
diff --git a/tests/wpt/meta/fetch/api/redirect/redirect-keepalive.any.js.ini b/tests/wpt/meta/fetch/api/redirect/redirect-keepalive.any.js.ini
index f61eb5b8e17..73c79c76452 100644
--- a/tests/wpt/meta/fetch/api/redirect/redirect-keepalive.any.js.ini
+++ b/tests/wpt/meta/fetch/api/redirect/redirect-keepalive.any.js.ini
@@ -1,5 +1,4 @@
[redirect-keepalive.any.html]
- expected: TIMEOUT
[[keepalive\][new window\][unload\] same-origin redirect]
expected: FAIL
diff --git a/tests/wpt/meta/fetch/fetch-later/headers/header-referrer-no-referrer-when-downgrade.tentative.https.html.ini b/tests/wpt/meta/fetch/fetch-later/headers/header-referrer-no-referrer-when-downgrade.tentative.https.html.ini
new file mode 100644
index 00000000000..3274b486b81
--- /dev/null
+++ b/tests/wpt/meta/fetch/fetch-later/headers/header-referrer-no-referrer-when-downgrade.tentative.https.html.ini
@@ -0,0 +1,3 @@
+[header-referrer-no-referrer-when-downgrade.tentative.https.html]
+ [Test referer header https://web-platform.test:8443]
+ expected: FAIL
diff --git a/tests/wpt/meta/fetch/fetch-later/headers/header-referrer-no-referrer.tentative.https.html.ini b/tests/wpt/meta/fetch/fetch-later/headers/header-referrer-no-referrer.tentative.https.html.ini
new file mode 100644
index 00000000000..f9977a9008e
--- /dev/null
+++ b/tests/wpt/meta/fetch/fetch-later/headers/header-referrer-no-referrer.tentative.https.html.ini
@@ -0,0 +1,3 @@
+[header-referrer-no-referrer.tentative.https.html]
+ [Test referer header ]
+ expected: FAIL
diff --git a/tests/wpt/meta/fetch/fetch-later/headers/header-referrer-origin-when-cross-origin.tentative.https.html.ini b/tests/wpt/meta/fetch/fetch-later/headers/header-referrer-origin-when-cross-origin.tentative.https.html.ini
new file mode 100644
index 00000000000..38a364e11ea
--- /dev/null
+++ b/tests/wpt/meta/fetch/fetch-later/headers/header-referrer-origin-when-cross-origin.tentative.https.html.ini
@@ -0,0 +1,6 @@
+[header-referrer-origin-when-cross-origin.tentative.https.html]
+ [Test referer header https://web-platform.test:8443]
+ expected: FAIL
+
+ [Test referer header https://www1.web-platform.test:8443]
+ expected: FAIL
diff --git a/tests/wpt/meta/fetch/fetch-later/headers/header-referrer-origin.tentative.https.html.ini b/tests/wpt/meta/fetch/fetch-later/headers/header-referrer-origin.tentative.https.html.ini
new file mode 100644
index 00000000000..06fe8584f00
--- /dev/null
+++ b/tests/wpt/meta/fetch/fetch-later/headers/header-referrer-origin.tentative.https.html.ini
@@ -0,0 +1,3 @@
+[header-referrer-origin.tentative.https.html]
+ [Test referer header https://www1.web-platform.test:8443]
+ expected: FAIL
diff --git a/tests/wpt/meta/fetch/fetch-later/headers/header-referrer-same-origin.tentative.https.html.ini b/tests/wpt/meta/fetch/fetch-later/headers/header-referrer-same-origin.tentative.https.html.ini
new file mode 100644
index 00000000000..ea9ac6e351c
--- /dev/null
+++ b/tests/wpt/meta/fetch/fetch-later/headers/header-referrer-same-origin.tentative.https.html.ini
@@ -0,0 +1,6 @@
+[header-referrer-same-origin.tentative.https.html]
+ [Test referer header ]
+ expected: FAIL
+
+ [Test referer header https://www1.web-platform.test:8443]
+ expected: FAIL
diff --git a/tests/wpt/meta/fetch/fetch-later/headers/header-referrer-strict-origin-when-cross-origin.tentative.https.html.ini b/tests/wpt/meta/fetch/fetch-later/headers/header-referrer-strict-origin-when-cross-origin.tentative.https.html.ini
new file mode 100644
index 00000000000..0bf2b43e93f
--- /dev/null
+++ b/tests/wpt/meta/fetch/fetch-later/headers/header-referrer-strict-origin-when-cross-origin.tentative.https.html.ini
@@ -0,0 +1,3 @@
+[header-referrer-strict-origin-when-cross-origin.tentative.https.html]
+ [Test referer header https://www1.web-platform.test:8443]
+ expected: FAIL
diff --git a/tests/wpt/meta/fetch/fetch-later/headers/header-referrer-strict-origin.tentative.https.html.ini b/tests/wpt/meta/fetch/fetch-later/headers/header-referrer-strict-origin.tentative.https.html.ini
new file mode 100644
index 00000000000..9c67727f1b1
--- /dev/null
+++ b/tests/wpt/meta/fetch/fetch-later/headers/header-referrer-strict-origin.tentative.https.html.ini
@@ -0,0 +1,3 @@
+[header-referrer-strict-origin.tentative.https.html]
+ [Test referer header https://web-platform.test:8443]
+ expected: FAIL
diff --git a/tests/wpt/meta/fetch/fetch-later/headers/header-referrer-unsafe-url.tentative.https.html.ini b/tests/wpt/meta/fetch/fetch-later/headers/header-referrer-unsafe-url.tentative.https.html.ini
new file mode 100644
index 00000000000..979914e33f8
--- /dev/null
+++ b/tests/wpt/meta/fetch/fetch-later/headers/header-referrer-unsafe-url.tentative.https.html.ini
@@ -0,0 +1,3 @@
+[header-referrer-unsafe-url.tentative.https.html]
+ [Test referer header https://web-platform.test:8443]
+ expected: FAIL
diff --git a/tests/wpt/meta/fetch/fetch-later/iframe.tentative.https.window.js.ini b/tests/wpt/meta/fetch/fetch-later/iframe.tentative.https.window.js.ini
new file mode 100644
index 00000000000..b3d4cb1d9f1
--- /dev/null
+++ b/tests/wpt/meta/fetch/fetch-later/iframe.tentative.https.window.js.ini
@@ -0,0 +1,2 @@
+[iframe.tentative.https.window.html]
+ expected: ERROR
diff --git a/tests/wpt/meta/fetch/fetch-later/new-window.tentative.https.window.js.ini b/tests/wpt/meta/fetch/fetch-later/new-window.tentative.https.window.js.ini
new file mode 100644
index 00000000000..1f36e0e5b51
--- /dev/null
+++ b/tests/wpt/meta/fetch/fetch-later/new-window.tentative.https.window.js.ini
@@ -0,0 +1,2 @@
+[new-window.tentative.https.window.html]
+ expected: ERROR
diff --git a/tests/wpt/meta/fetch/fetch-later/policies/csp-allowed.tentative.https.window.js.ini b/tests/wpt/meta/fetch/fetch-later/policies/csp-allowed.tentative.https.window.js.ini
new file mode 100644
index 00000000000..357487889e9
--- /dev/null
+++ b/tests/wpt/meta/fetch/fetch-later/policies/csp-allowed.tentative.https.window.js.ini
@@ -0,0 +1,2 @@
+[csp-allowed.tentative.https.window.html]
+ expected: ERROR
diff --git a/tests/wpt/meta/fetch/fetch-later/policies/csp-blocked.tentative.https.window.js.ini b/tests/wpt/meta/fetch/fetch-later/policies/csp-blocked.tentative.https.window.js.ini
new file mode 100644
index 00000000000..f6d883b2101
--- /dev/null
+++ b/tests/wpt/meta/fetch/fetch-later/policies/csp-blocked.tentative.https.window.js.ini
@@ -0,0 +1,2 @@
+[csp-blocked.tentative.https.window.html]
+ expected: ERROR
diff --git a/tests/wpt/meta/fetch/fetch-later/policies/csp-redirect-to-blocked.tentative.https.window.js.ini b/tests/wpt/meta/fetch/fetch-later/policies/csp-redirect-to-blocked.tentative.https.window.js.ini
new file mode 100644
index 00000000000..23cc9814012
--- /dev/null
+++ b/tests/wpt/meta/fetch/fetch-later/policies/csp-redirect-to-blocked.tentative.https.window.js.ini
@@ -0,0 +1,2 @@
+[csp-redirect-to-blocked.tentative.https.window.html]
+ expected: ERROR
diff --git a/tests/wpt/meta/fetch/metadata/generated/css-images.sub.tentative.html.ini b/tests/wpt/meta/fetch/metadata/generated/css-images.sub.tentative.html.ini
index 8099defc928..4b5c3e26586 100644
--- a/tests/wpt/meta/fetch/metadata/generated/css-images.sub.tentative.html.ini
+++ b/tests/wpt/meta/fetch/metadata/generated/css-images.sub.tentative.html.ini
@@ -185,6 +185,3 @@
[border-image sec-fetch-site - HTTPS downgrade (header not sent)]
expected: FAIL
-
- [background-image sec-fetch-mode - Not sent to non-trustworthy same-site destination]
- expected: TIMEOUT
diff --git a/tests/wpt/meta/hr-time/raf-coarsened-time.https.html.ini b/tests/wpt/meta/hr-time/raf-coarsened-time.https.html.ini
new file mode 100644
index 00000000000..b4991611fcf
--- /dev/null
+++ b/tests/wpt/meta/hr-time/raf-coarsened-time.https.html.ini
@@ -0,0 +1,2 @@
+[raf-coarsened-time.https.html]
+ expected: ERROR
diff --git a/tests/wpt/meta/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/order-in-bfcache-restore.html.ini b/tests/wpt/meta/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/order-in-bfcache-restore.html.ini
new file mode 100644
index 00000000000..46f10274f9f
--- /dev/null
+++ b/tests/wpt/meta/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/order-in-bfcache-restore.html.ini
@@ -0,0 +1,4 @@
+[order-in-bfcache-restore.html]
+ expected: TIMEOUT
+ [pagereveal event fires and in correct order on restoration from BFCache]
+ expected: TIMEOUT
diff --git a/tests/wpt/meta/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/order-in-new-document-navigation.html.ini b/tests/wpt/meta/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/order-in-new-document-navigation.html.ini
new file mode 100644
index 00000000000..721a89932a1
--- /dev/null
+++ b/tests/wpt/meta/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/order-in-new-document-navigation.html.ini
@@ -0,0 +1,3 @@
+[order-in-new-document-navigation.html]
+ [pagereveal event fires and in correct order on new-document navigation]
+ expected: FAIL
diff --git a/tests/wpt/meta/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/order-in-prerender-activation.html.ini b/tests/wpt/meta/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/order-in-prerender-activation.html.ini
new file mode 100644
index 00000000000..b6c1d6dbec6
--- /dev/null
+++ b/tests/wpt/meta/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/order-in-prerender-activation.html.ini
@@ -0,0 +1,2 @@
+[order-in-prerender-activation.html]
+ expected: ERROR
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 bf5454c35e1..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
@@ -5,8 +5,8 @@
[load & pageshow events do not fire on contentWindow of <iframe> element created with src='about:blank?foo']
expected: FAIL
- [load & pageshow events do not fire on contentWindow of <iframe> element created with src='']
+ [load & pageshow events do not fire on contentWindow of <iframe> element created with src='about:blank#foo']
expected: FAIL
- [load & pageshow events do not fire on contentWindow of <iframe> element created with src='about:blank#foo']
+ [load & pageshow events do not fire on contentWindow of <iframe> element created with src='about:blank']
expected: FAIL
diff --git a/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/load-pageshow-events-window-open.html.ini b/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/load-pageshow-events-window-open.html.ini
index 324db3d9b35..5aef7ce66ce 100644
--- a/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/load-pageshow-events-window-open.html.ini
+++ b/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/load-pageshow-events-window-open.html.ini
@@ -10,3 +10,6 @@
[load event does not fire on window.open('about:blank?foo')]
expected: FAIL
+
+ [load event does not fire on window.open('about:blank')]
+ expected: FAIL
diff --git a/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/javascript-url-return-value-handling-dynamic.html.ini b/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/javascript-url-return-value-handling-dynamic.html.ini
index f27acdd3b9d..78240a2f463 100644
--- a/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/javascript-url-return-value-handling-dynamic.html.ini
+++ b/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/javascript-url-return-value-handling-dynamic.html.ini
@@ -4,3 +4,15 @@
[Test javascript URL string return values in direct and indirect (target) frame contexts. 9]
expected: FAIL
+
+ [0041 set in href="" targeting a frame and clicked]
+ expected: FAIL
+
+ [0080 00FF set in href="" targeting a frame and clicked]
+ expected: FAIL
+
+ [0080 00FF 0100 set in href="" targeting a frame and clicked]
+ expected: FAIL
+
+ [D83D DE0D set in href="" targeting a frame and clicked]
+ expected: FAIL
diff --git a/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-cross-origin.sub.window.js.ini b/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-cross-origin.sub.window.js.ini
new file mode 100644
index 00000000000..4ecd6d9f753
--- /dev/null
+++ b/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-cross-origin.sub.window.js.ini
@@ -0,0 +1,3 @@
+[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/html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-same-origin.window.js.ini b/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-same-origin.window.js.ini
deleted file mode 100644
index 7dc346632a4..00000000000
--- a/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-same-origin.window.js.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[navigation-unload-same-origin.window.html]
- [Same-origin navigation started from unload handler must be ignored]
- expected: FAIL
diff --git a/tests/wpt/meta/html/browsers/browsing-the-web/overlapping-navigations-and-traversals/nav-cancelation-2.sub.html.ini b/tests/wpt/meta/html/browsers/browsing-the-web/overlapping-navigations-and-traversals/nav-cancelation-2.sub.html.ini
index 9f7f24f662e..0e40ffc0656 100644
--- a/tests/wpt/meta/html/browsers/browsing-the-web/overlapping-navigations-and-traversals/nav-cancelation-2.sub.html.ini
+++ b/tests/wpt/meta/html/browsers/browsing-the-web/overlapping-navigations-and-traversals/nav-cancelation-2.sub.html.ini
@@ -1,3 +1,4 @@
[nav-cancelation-2.sub.html]
+ expected: TIMEOUT
[grandparent cancels a pending navigation in a cross-origin grandchild]
- expected: FAIL
+ expected: TIMEOUT
diff --git a/tests/wpt/meta/html/browsers/history/the-history-interface/traverse-during-unload.html.ini b/tests/wpt/meta/html/browsers/history/the-history-interface/traverse-during-unload.html.ini
new file mode 100644
index 00000000000..f5b7b25324f
--- /dev/null
+++ b/tests/wpt/meta/html/browsers/history/the-history-interface/traverse-during-unload.html.ini
@@ -0,0 +1,4 @@
+[traverse-during-unload.html]
+ expected: TIMEOUT
+ [Traversing the history during unload]
+ expected: TIMEOUT
diff --git a/tests/wpt/meta-legacy-layout/html/browsers/history/the-history-interface/traverse_the_history_5.html.ini b/tests/wpt/meta/html/browsers/history/the-history-interface/traverse_the_history_5.html.ini
index 7a5fcb79165..7a5fcb79165 100644
--- a/tests/wpt/meta-legacy-layout/html/browsers/history/the-history-interface/traverse_the_history_5.html.ini
+++ b/tests/wpt/meta/html/browsers/history/the-history-interface/traverse_the_history_5.html.ini
diff --git a/tests/wpt/meta/html/browsers/origin/cross-origin-objects/cross-origin-objects.html.ini b/tests/wpt/meta/html/browsers/origin/cross-origin-objects/cross-origin-objects.html.ini
index 24c9e5d3926..90eb9ed743b 100644
--- a/tests/wpt/meta/html/browsers/origin/cross-origin-objects/cross-origin-objects.html.ini
+++ b/tests/wpt/meta/html/browsers/origin/cross-origin-objects/cross-origin-objects.html.ini
@@ -1,5 +1,4 @@
[cross-origin-objects.html]
- expected: TIMEOUT
[Basic sanity-checking (cross-origin)]
expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/browsers/the-window-object/open-close/creating_browsing_context_test_01.html.ini b/tests/wpt/meta/html/browsers/the-window-object/open-close/creating_browsing_context_test_01.html.ini
index 4b4820d1729..4b4820d1729 100644
--- a/tests/wpt/meta-legacy-layout/html/browsers/the-window-object/open-close/creating_browsing_context_test_01.html.ini
+++ b/tests/wpt/meta/html/browsers/the-window-object/open-close/creating_browsing_context_test_01.html.ini
diff --git a/tests/wpt/meta/html/browsers/windows/embedded-opener-remove-frame.html.ini b/tests/wpt/meta/html/browsers/windows/embedded-opener-remove-frame.html.ini
index 613bed9352d..9df06805f99 100644
--- a/tests/wpt/meta/html/browsers/windows/embedded-opener-remove-frame.html.ini
+++ b/tests/wpt/meta/html/browsers/windows/embedded-opener-remove-frame.html.ini
@@ -1,5 +1,5 @@
[embedded-opener-remove-frame.html]
- expected: CRASH
+ expected: TIMEOUT
[opener of discarded nested browsing context]
expected: FAIL
diff --git a/tests/wpt/meta/html/dom/elements/global-attributes/dir-auto-form-associated.window.js.ini b/tests/wpt/meta/html/dom/elements/global-attributes/dir-auto-form-associated.window.js.ini
new file mode 100644
index 00000000000..9b19b29d20e
--- /dev/null
+++ b/tests/wpt/meta/html/dom/elements/global-attributes/dir-auto-form-associated.window.js.ini
@@ -0,0 +1,66 @@
+[dir-auto-form-associated.window.html]
+ [<input dir=auto type=hidden> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=text> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=search> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=tel> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=url> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=email> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=password> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=submit> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=reset> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=button> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=date> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=month> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=week> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=time> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=datetime-local> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=number> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=range> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=color> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=checkbox> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=radio> directionality]
+ expected: FAIL
+
+ [<input dir=auto type=image> directionality]
+ expected: FAIL
+
+ [<textarea dir=auto> directionality]
+ expected: FAIL
diff --git a/tests/wpt/meta/html/dom/elements/global-attributes/lang-attribute.window.js.ini b/tests/wpt/meta/html/dom/elements/global-attributes/lang-attribute.window.js.ini
new file mode 100644
index 00000000000..9a9467a8817
--- /dev/null
+++ b/tests/wpt/meta/html/dom/elements/global-attributes/lang-attribute.window.js.ini
@@ -0,0 +1,3 @@
+[lang-attribute.window.html]
+ [unnamespaced lang attribute only works on elements in the HTML namespace]
+ expected: FAIL
diff --git a/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-1.html.ini b/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-1.html.ini
index 24903b5f66f..7d28d586f51 100644
--- a/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-1.html.ini
+++ b/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-1.html.ini
@@ -1,4 +1,3 @@
[iframe_sandbox_popups_escaping-1.html]
- expected: TIMEOUT
[Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used]
- expected: TIMEOUT
+ expected: FAIL
diff --git a/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html.ini b/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html.ini
index bbc1f35d8d9..e8872b3585b 100644
--- a/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html.ini
+++ b/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html.ini
@@ -1,3 +1,4 @@
[iframe_sandbox_popups_nonescaping-1.html]
+ expected: TIMEOUT
[Check that popups from a sandboxed iframe do not escape the sandbox]
- expected: FAIL
+ expected: NOTRUN
diff --git a/tests/wpt/meta/html/semantics/embedded-content/the-img-element/non-active-document.html.ini b/tests/wpt/meta/html/semantics/embedded-content/the-img-element/non-active-document.html.ini
index 3cdeb8ebcbc..47b45e65a1c 100644
--- a/tests/wpt/meta/html/semantics/embedded-content/the-img-element/non-active-document.html.ini
+++ b/tests/wpt/meta/html/semantics/embedded-content/the-img-element/non-active-document.html.ini
@@ -1,3 +1,9 @@
[non-active-document.html]
[DOMParser]
expected: FAIL
+
+ [createHTMLDocument]
+ expected: FAIL
+
+ [<template>]
+ expected: FAIL
diff --git a/tests/wpt/meta/html/semantics/invokers/invokeelement-interface.tentative.html.ini b/tests/wpt/meta/html/semantics/invokers/invokeelement-interface.tentative.html.ini
index e1534b63047..e8781936e24 100644
--- a/tests/wpt/meta/html/semantics/invokers/invokeelement-interface.tentative.html.ini
+++ b/tests/wpt/meta/html/semantics/invokers/invokeelement-interface.tentative.html.ini
@@ -31,3 +31,6 @@
[invokeAction reflects tostring value 2]
expected: FAIL
+
+ [invokeAction reflects same casing]
+ expected: FAIL
diff --git a/tests/wpt/meta/html/webappapis/dynamic-markup-insertion/document-write/module-static-import-delayed.html.ini b/tests/wpt/meta/html/webappapis/dynamic-markup-insertion/document-write/module-static-import-delayed.html.ini
new file mode 100644
index 00000000000..53acb938c1b
--- /dev/null
+++ b/tests/wpt/meta/html/webappapis/dynamic-markup-insertion/document-write/module-static-import-delayed.html.ini
@@ -0,0 +1,3 @@
+[module-static-import-delayed.html]
+ [document.write in an imported module]
+ 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 1053fb90051..6206f8c0210 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
@@ -2,6 +2,3 @@
expected: TIMEOUT
[The incumbent settings object while executing the compiled callback via Web IDL's invoke must be that of the node document]
expected: TIMEOUT
-
- [The entry settings object while executing the compiled callback via Web IDL's invoke must be that of the node document]
- expected: FAIL
diff --git a/tests/wpt/meta/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-job-queue/promise-job-entry-different-function-realm.html.ini b/tests/wpt/meta/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-job-queue/promise-job-entry-different-function-realm.html.ini
index dbe1def99e3..7237f5792de 100644
--- a/tests/wpt/meta/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-job-queue/promise-job-entry-different-function-realm.html.ini
+++ b/tests/wpt/meta/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-job-queue/promise-job-entry-different-function-realm.html.ini
@@ -1,9 +1,10 @@
[promise-job-entry-different-function-realm.html]
+ expected: TIMEOUT
[Fulfillment handler on fulfilled promise]
expected: FAIL
[Rejection handler on pending-then-rejected promise]
- expected: FAIL
+ expected: TIMEOUT
[Thenable resolution]
expected: FAIL
@@ -12,4 +13,4 @@
expected: FAIL
[Fulfillment handler on pending-then-fulfilled promise]
- expected: FAIL
+ expected: TIMEOUT
diff --git a/tests/wpt/meta/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-job-queue/promise-job-entry.html.ini b/tests/wpt/meta/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-job-queue/promise-job-entry.html.ini
index 8bcf3a07de4..31bfd644df0 100644
--- a/tests/wpt/meta/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-job-queue/promise-job-entry.html.ini
+++ b/tests/wpt/meta/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-job-queue/promise-job-entry.html.ini
@@ -1,10 +1,9 @@
[promise-job-entry.html]
- expected: TIMEOUT
[Fulfillment handler on fulfilled promise]
expected: FAIL
[Rejection handler on pending-then-rejected promise]
- expected: TIMEOUT
+ expected: FAIL
[Sanity check: this all works as expected with no promises involved]
expected: FAIL
@@ -16,4 +15,4 @@
expected: FAIL
[Fulfillment handler on pending-then-fulfilled promise]
- 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 49b17a921b5..71ca4ed5411 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: TIMEOUT
+ expected: FAIL
[mime-type 17 : text/html;charset=\x0cgbk]
- expected: NOTRUN
+ expected: TIMEOUT
[mime-type 18 : text/html;\x0bcharset=gbk]
expected: NOTRUN
diff --git a/tests/wpt/meta/wasm/jsapi/functions/entry.html.ini b/tests/wpt/meta/wasm/jsapi/functions/entry.html.ini
index 145d4a8fe37..2ab19558726 100644
--- a/tests/wpt/meta/wasm/jsapi/functions/entry.html.ini
+++ b/tests/wpt/meta/wasm/jsapi/functions/entry.html.ini
@@ -1,6 +1,7 @@
[entry.html]
+ expected: TIMEOUT
[Start function]
- expected: FAIL
+ expected: TIMEOUT
[Sanity check: this all works as expected synchronously]
expected: FAIL
diff --git a/tests/wpt/meta/wasm/jsapi/gc/casts.tentative.any.js.ini b/tests/wpt/meta/wasm/jsapi/gc/casts.tentative.any.js.ini
new file mode 100644
index 00000000000..0b499ced6d7
--- /dev/null
+++ b/tests/wpt/meta/wasm/jsapi/gc/casts.tentative.any.js.ini
@@ -0,0 +1,5 @@
+[casts.tentative.any.worker.html]
+ expected: ERROR
+
+[casts.tentative.any.html]
+ expected: ERROR
diff --git a/tests/wpt/meta/wasm/jsapi/gc/exported-object.tentative.any.js.ini b/tests/wpt/meta/wasm/jsapi/gc/exported-object.tentative.any.js.ini
new file mode 100644
index 00000000000..59dd05d2b08
--- /dev/null
+++ b/tests/wpt/meta/wasm/jsapi/gc/exported-object.tentative.any.js.ini
@@ -0,0 +1,5 @@
+[exported-object.tentative.any.worker.html]
+ expected: ERROR
+
+[exported-object.tentative.any.html]
+ expected: ERROR
diff --git a/tests/wpt/meta/wasm/jsapi/gc/i31.tentative.any.js.ini b/tests/wpt/meta/wasm/jsapi/gc/i31.tentative.any.js.ini
new file mode 100644
index 00000000000..07c9b76b544
--- /dev/null
+++ b/tests/wpt/meta/wasm/jsapi/gc/i31.tentative.any.js.ini
@@ -0,0 +1,5 @@
+[i31.tentative.any.html]
+ expected: ERROR
+
+[i31.tentative.any.worker.html]
+ expected: ERROR
diff --git a/tests/wpt/meta/webmessaging/with-ports/017.html.ini b/tests/wpt/meta/webmessaging/with-ports/017.html.ini
deleted file mode 100644
index c7946fc91b4..00000000000
--- a/tests/wpt/meta/webmessaging/with-ports/017.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[017.html]
- expected: TIMEOUT
- [origin of the script that invoked the method, about:blank]
- expected: TIMEOUT
diff --git a/tests/wpt/meta/webmessaging/with-ports/018.html.ini b/tests/wpt/meta/webmessaging/with-ports/018.html.ini
new file mode 100644
index 00000000000..b7b36c1d3a4
--- /dev/null
+++ b/tests/wpt/meta/webmessaging/with-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/webmessaging/without-ports/018.html.ini b/tests/wpt/meta/webmessaging/without-ports/018.html.ini
new file mode 100644
index 00000000000..b7b36c1d3a4
--- /dev/null
+++ b/tests/wpt/meta/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/workers/constructors/Worker/Worker-constructor.html.ini b/tests/wpt/meta/workers/constructors/Worker/Worker-constructor.html.ini
deleted file mode 100644
index 80f9a4f15b8..00000000000
--- a/tests/wpt/meta/workers/constructors/Worker/Worker-constructor.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[Worker-constructor.html]
- expected: ERROR
diff --git a/tests/wpt/tests/.github/workflows/documentation.yml b/tests/wpt/tests/.github/workflows/documentation.yml
index 00c7bb22627..1d57acc6256 100644
--- a/tests/wpt/tests/.github/workflows/documentation.yml
+++ b/tests/wpt/tests/.github/workflows/documentation.yml
@@ -21,7 +21,7 @@ jobs:
with:
python-version: '3.11'
- name: Set up Node
- uses: actions/setup-node@v3
+ uses: actions/setup-node@v4
with:
node-version: '14'
- name: Set up Virtualenv
diff --git a/tests/wpt/tests/accelerometer/Accelerometer-iframe-access.https.html b/tests/wpt/tests/accelerometer/Accelerometer-iframe-access.https.html
index bec1705780f..56005696a7f 100644
--- a/tests/wpt/tests/accelerometer/Accelerometer-iframe-access.https.html
+++ b/tests/wpt/tests/accelerometer/Accelerometer-iframe-access.https.html
@@ -6,12 +6,15 @@
<link rel="help" href="https://www.w3.org/TR/accelerometer/">
<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="/generic-sensor/resources/generic-sensor-helpers.js"></script>
<script src="/generic-sensor/generic-sensor-iframe-tests.sub.js"></script>
<script src="/generic-sensor/generic-sensor-feature-policy-test.sub.js"></script>
+<script src="resources/sensor-data.js"></script>
<div id="log"></div>
<script>
-run_generic_sensor_iframe_tests('Accelerometer');
-run_generic_sensor_iframe_tests('LinearAccelerationSensor');
-run_generic_sensor_iframe_tests('GravitySensor');
+run_generic_sensor_iframe_tests(kAccelerometerSensorData, kAccelerometerReadings);
+run_generic_sensor_iframe_tests(kLinearAccelerationSensorData, kAccelerometerReadings);
+run_generic_sensor_iframe_tests(kGravitySensorData, kAccelerometerReadings);
</script>
diff --git a/tests/wpt/tests/accelerometer/Accelerometer.https.html b/tests/wpt/tests/accelerometer/Accelerometer.https.html
index 0db87d2efc3..d422fef7264 100644
--- a/tests/wpt/tests/accelerometer/Accelerometer.https.html
+++ b/tests/wpt/tests/accelerometer/Accelerometer.https.html
@@ -6,28 +6,12 @@
<link rel="help" href="https://www.w3.org/TR/accelerometer/">
<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="/page-visibility/resources/window_state_context.js"></script>
<script src="/generic-sensor/resources/generic-sensor-helpers.js"></script>
<script src="/generic-sensor/generic-sensor-tests.js"></script>
+<script src="resources/sensor-data.js"></script>
<script>
-
-'use strict';
-
-const kReadings = {
- readings: [
- [1.12345, 2.12345, 3.12345]
- ],
- expectedReadings: [
- [1.12345, 2.12345, 3.12345]
- ],
- expectedRemappedReadings: [
- [-2.12345, 1.12345, 3.12345]
- ]
-};
-
-runGenericSensorTests(
- 'Accelerometer',
- kReadings,
- verifyXyzSensorReading,
- ['accelerometer']);
-
+runGenericSensorTests(kAccelerometerSensorData, kAccelerometerReadings);
</script>
diff --git a/tests/wpt/tests/accelerometer/GravitySensor.https.html b/tests/wpt/tests/accelerometer/GravitySensor.https.html
index 6fb21e55728..0f98f3e00de 100644
--- a/tests/wpt/tests/accelerometer/GravitySensor.https.html
+++ b/tests/wpt/tests/accelerometer/GravitySensor.https.html
@@ -6,28 +6,16 @@
<link rel="help" href="https://www.w3.org/TR/accelerometer/">
<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="/page-visibility/resources/window_state_context.js"></script>
<script src="/generic-sensor/resources/generic-sensor-helpers.js"></script>
<script src="/generic-sensor/generic-sensor-tests.js"></script>
+<script src="resources/sensor-data.js"></script>
<script>
'use strict';
-const kReadings = {
- readings: [
- [1.12345, 2.12345, 3.12345]
- ],
- expectedReadings: [
- [1.12345, 2.12345, 3.12345]
- ],
- expectedRemappedReadings: [
- [-2.12345, 1.12345, 3.12345]
- ]
-};
-
-runGenericSensorTests(
- 'GravitySensor',
- kReadings,
- verifyXyzSensorReading,
- ['accelerometer']);
+runGenericSensorTests(kGravitySensorData, kAccelerometerReadings);
</script>
diff --git a/tests/wpt/tests/accelerometer/LinearAccelerationSensor.https.html b/tests/wpt/tests/accelerometer/LinearAccelerationSensor.https.html
index 8dd3446f409..91035cc9628 100644
--- a/tests/wpt/tests/accelerometer/LinearAccelerationSensor.https.html
+++ b/tests/wpt/tests/accelerometer/LinearAccelerationSensor.https.html
@@ -6,28 +6,16 @@
<link rel="help" href="https://www.w3.org/TR/accelerometer/">
<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="/page-visibility/resources/window_state_context.js"></script>
<script src="/generic-sensor/resources/generic-sensor-helpers.js"></script>
<script src="/generic-sensor/generic-sensor-tests.js"></script>
+<script src="resources/sensor-data.js"></script>
<script>
'use strict';
-const kReadings = {
- readings: [
- [1.12345, 2.12345, 3.12345]
- ],
- expectedReadings: [
- [1.12345, 2.12345, 3.12345]
- ],
- expectedRemappedReadings: [
- [-2.12345, 1.12345, 3.12345]
- ]
-};
-
-runGenericSensorTests(
- 'LinearAccelerationSensor',
- kReadings,
- verifyXyzSensorReading,
- ['accelerometer']);
+runGenericSensorTests(kLinearAccelerationSensorData, kAccelerometerReadings);
</script>
diff --git a/tests/wpt/tests/accelerometer/resources/sensor-data.js b/tests/wpt/tests/accelerometer/resources/sensor-data.js
new file mode 100644
index 00000000000..6f56cfdbeb6
--- /dev/null
+++ b/tests/wpt/tests/accelerometer/resources/sensor-data.js
@@ -0,0 +1,34 @@
+'use strict';
+
+const kAccelerometerSensorData = {
+ sensorName: 'Accelerometer',
+ permissionName: 'accelerometer',
+ testDriverName: 'accelerometer',
+ featurePolicyNames: ['accelerometer']
+};
+
+const kGravitySensorData = {
+ sensorName: 'GravitySensor',
+ permissionName: 'accelerometer',
+ testDriverName: 'gravity',
+ featurePolicyNames: ['accelerometer']
+};
+
+const kLinearAccelerationSensorData = {
+ sensorName: 'LinearAccelerationSensor',
+ permissionName: 'accelerometer',
+ testDriverName: 'linear-acceleration',
+ featurePolicyNames: ['accelerometer']
+};
+
+const kAccelerometerReadings = {
+ readings: [
+ { x: 1.12345, y: 2.12345, z: 3.12345 }
+ ],
+ expectedReadings: [
+ { x: 1.1, y: 2.1, z: 3.1 }
+ ],
+ expectedRemappedReadings: [
+ { x: -2.1, y: 1.1, z: 3.1 }
+ ]
+};
diff --git a/tests/wpt/tests/ambient-light/AmbientLightSensor-iframe-access.https.html b/tests/wpt/tests/ambient-light/AmbientLightSensor-iframe-access.https.html
index 5fedd5fb7a9..765c1bee1f8 100644
--- a/tests/wpt/tests/ambient-light/AmbientLightSensor-iframe-access.https.html
+++ b/tests/wpt/tests/ambient-light/AmbientLightSensor-iframe-access.https.html
@@ -5,10 +5,13 @@
<link rel="help" href="https://w3c.github.io/ambient-light/">
<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="/generic-sensor/resources/generic-sensor-helpers.js"></script>
<script src="/generic-sensor/generic-sensor-iframe-tests.sub.js"></script>
<script src="/generic-sensor/generic-sensor-feature-policy-test.sub.js"></script>
+<script src="resources/sensor-data.js"></script>
<div id="log"></div>
<script>
-run_generic_sensor_iframe_tests('AmbientLightSensor');
+run_generic_sensor_iframe_tests(kSensorData, kReadings);
</script>
diff --git a/tests/wpt/tests/ambient-light/AmbientLightSensor.https.html b/tests/wpt/tests/ambient-light/AmbientLightSensor.https.html
index a8c65e4d3fa..f2ed655082e 100644
--- a/tests/wpt/tests/ambient-light/AmbientLightSensor.https.html
+++ b/tests/wpt/tests/ambient-light/AmbientLightSensor.https.html
@@ -6,58 +6,12 @@
<link rel="help" href="https://www.w3.org/TR/ambient-light/">
<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="/page-visibility/resources/window_state_context.js"></script>
<script src="/generic-sensor/resources/generic-sensor-helpers.js"></script>
<script src="/generic-sensor/generic-sensor-tests.js"></script>
+<script src="resources/sensor-data.js"></script>
<script>
-
-'use strict';
-
-const kReadings = {
- readings: [
- // Readings are selected so that illuminance significance check causes
- // the following to happen:
- // 1. First two values test situation when two values would be rounded
- // to same value. As the second value would be rounded to same value
- // as first it won't trigger reading event.
- // 2. New value is set to 24. And test checks it is correctly rounded to
- // 0.
- // 3. New reading is attempted to set to 35.
- // 4. Value is read from sensor and compared new reading. But as new
- // reading was not significantly different compared to initial, for
- // privacy reasons, service returns the initial value.
- // 5. New value is set to 49. And test checks it is correctly rounded to
- // 50. New value is allowed as it is significantly different compared
- // to old value (24).
- // 6. New reading is attempted to set to 35.
- // 7. Value is read from sensor and compared new reading. But as new
- // reading was not significantly different compared to initial, for
- // privacy reasons, service returns the initial value.
- // 8. New value is set to 23. And test checks it is correctly rounded to
- // 0. New value is allowed as it is significantly different compared
- // to old value (49).
- //
- // Note: Readings and expectedReadings wraps around correctly as next
- // value would be 150 (output from 127).
- [127],
- [165],
- [24],
- [35],
- [49],
- [35],
- [23]
- ],
- expectedReadings: [
- [150], // output from 127
- [0], // output from 24
- [50], // output from 49
- [0] // output from 23
- ]
-};
-
-runGenericSensorTests(
- 'AmbientLightSensor',
- kReadings,
- verifyAlsSensorReading,
- ['ambient-light-sensor']);
-
+runGenericSensorTests(kSensorData, kReadings);
</script>
diff --git a/tests/wpt/tests/ambient-light/resources/sensor-data.js b/tests/wpt/tests/ambient-light/resources/sensor-data.js
new file mode 100644
index 00000000000..c1f7bd5ca0f
--- /dev/null
+++ b/tests/wpt/tests/ambient-light/resources/sensor-data.js
@@ -0,0 +1,47 @@
+'use strict';
+
+const kSensorData = {
+ sensorName: 'AmbientLightSensor',
+ permissionName: 'ambient-light-sensor',
+ testDriverName: 'ambient-light',
+ featurePolicyNames: ['ambient-light-sensor']
+};
+
+const kReadings = {
+ readings: [
+ // Readings are selected so that illuminance significance check causes
+ // the following to happen:
+ // 1. First two values test situation when two values would be rounded
+ // to same value. As the second value would be rounded to same value
+ // as first it won't trigger reading event.
+ // 2. New value is set to 24. And test checks it is correctly rounded to
+ // 0.
+ // 3. New reading is attempted to set to 35.
+ // 4. Value is read from sensor and compared new reading. But as new
+ // reading was not significantly different compared to initial, for
+ // privacy reasons, service returns the initial value.
+ // 5. New value is set to 49. And test checks it is correctly rounded to
+ // 50. New value is allowed as it is significantly different compared
+ // to old value (24).
+ // 6. New reading is attempted to set to 35.
+ // 7. Value is read from sensor and compared new reading. But as new
+ // reading was not significantly different compared to initial, for
+ // privacy reasons, service returns the initial value.
+ // 8. New value is set to 23. And test checks it is correctly rounded to
+ // 0. New value is allowed as it is significantly different compared
+ // to old value (49).
+ //
+ // Note: Readings and expectedReadings wraps around correctly as next
+ // value would be 150 (output from 127).
+ { illuminance: 127 }, { illuminance: 165 }, { illuminance: 24 }, {
+ illuminance:
+ 35
+ }, { illuminance: 49 }, { illuminance: 35 }, { illuminance: 23 }
+ ],
+ expectedReadings: [
+ { illuminance: 150 }, // output from 127
+ { illuminance: 0 }, // output from 24
+ { illuminance: 50 }, // output from 49
+ { illuminance: 0 } // output from 23
+ ]
+};
diff --git a/tests/wpt/tests/clipboard-apis/clipboard-item.https.html b/tests/wpt/tests/clipboard-apis/clipboard-item.https.html
index 9ed6f583bde..b50a1c97d74 100644
--- a/tests/wpt/tests/clipboard-apis/clipboard-item.https.html
+++ b/tests/wpt/tests/clipboard-apis/clipboard-item.https.html
@@ -95,4 +95,18 @@ promise_test(async () => {
const text = await (new Response(blob)).text();
assert_equals(text, 'xxx');
}, "getType(DOMString invalid type) converts DOMString to Blob");
+
+promise_test(async () => {
+ assert_true(ClipboardItem.supports('text/plain'));
+ assert_true(ClipboardItem.supports('text/html'));
+ assert_true(ClipboardItem.supports('image/png'));
+ 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('not a/real type'));
+}, "supports(DOMString) returns true for types that are supported, false otherwise");
</script>
diff --git a/tests/wpt/tests/close-watcher/closewatcher-dialog-popover.html b/tests/wpt/tests/close-watcher/closewatcher-dialog-popover.html
index f6443c4317e..50d5cb7a4ca 100644
--- a/tests/wpt/tests/close-watcher/closewatcher-dialog-popover.html
+++ b/tests/wpt/tests/close-watcher/closewatcher-dialog-popover.html
@@ -6,6 +6,7 @@
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/resources/testdriver-actions.js"></script>
+<script src="/common/top-layer.js"></script>
<script src="resources/helpers.js"></script>
<button id=b0>button</button>
@@ -73,19 +74,22 @@ promise_test(async t => {
assert_true(dialog.hasAttribute('open'), 'The dialog should be open.');
assert_true(popover.matches(':popover-open'), 'The popover should be open.');
- await dialogResilientBless(popover, () => sendCloseRequest());
+ await blessTopLayer(popover);
+ await sendCloseRequest();
await waitForPotentialCloseEvent();
assert_false(popover.matches(':popover-open'), 'First close request: The popover should be closed.');
assert_true(dialog.hasAttribute('open'), 'First close request: The dialog should be open.');
assert_array_equals(events, []);
- await dialogResilientBless(dialog, () => sendCloseRequest());
+ await blessTopLayer(dialog);
+ await sendCloseRequest();
await waitForPotentialCloseEvent();
assert_false(popover.matches(':popover-open'), 'Second close request: The popover should be closed.');
assert_false(dialog.hasAttribute('open'), 'Second close request: The dialog should be closed.');
assert_array_equals(events, ['dialog cancel', 'dialog close']);
- await dialogResilientBless(closeWatcher, () => sendCloseRequest());
+ await test_driver.bless();
+ await sendCloseRequest();
await waitForPotentialCloseEvent();
assert_false(popover.matches(':popover-open'), 'Third close request: The popover should be closed.');
assert_false(dialog.hasAttribute('open'), 'Third close request: The dialog should be closed.');
diff --git a/tests/wpt/tests/close-watcher/dialog-cancel-events-closewatcher.html b/tests/wpt/tests/close-watcher/dialog-cancel-events-closewatcher.html
deleted file mode 100644
index 5b1da9a2e37..00000000000
--- a/tests/wpt/tests/close-watcher/dialog-cancel-events-closewatcher.html
+++ /dev/null
@@ -1,55 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <title>Test cancel event is fired when the dialog is closed by user interaction</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>
- <link rel="help" href="https://bugs.webkit.org/show_bug.cgi?id=227534">
- <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1322947">
-</head>
-<body>
-<p>Test cancel event is fired when the dialog is closed by user interaction</p>
-<dialog>
- <p>Hello World</p>
- <button>user activation button</button>
-</dialog>
-<script>
- setup({ single_test: true });
-
- var hasCancelEventFired = false;
- var hasCloseEventFired = false;
-
- const dialog = document.querySelector("dialog");
-
- dialog.addEventListener("cancel", function(event) {
- assert_true(true, "cancel event is fired");
- assert_true(event.cancelable, "cancel event should be cancelable");
- assert_false(hasCancelEventFired, "cancel event should only be fired once");
- assert_false(hasCloseEventFired, "close event should be fired after cancel event");
- hasCancelEventFired = true;
- });
-
- dialog.addEventListener("close", function() {
- assert_true(true, "close event is fired");
- assert_false(hasCloseEventFired, "close event should only be fired once");
- assert_true(hasCancelEventFired, "cancel event should be fired before close event");
- hasCloseEventFired = true;
- done();
- });
-
- dialog.showModal();
-
- (async () => {
- // Pressing escape on the dialog needs user activation or else the cancel event won't be fired.
- const button = dialog.querySelector('button');
- const buttonClickPromise = new Promise(resolve => button.onclick = resolve);
- await test_driver.click(button);
- await buttonClickPromise;
-
- test_driver.send_keys(document.documentElement, "\uE00C"); // ESC key
- })();
-</script>
-</body>
-</html>
diff --git a/tests/wpt/tests/close-watcher/dialog-cancel-preventDefault-closewatcher.html b/tests/wpt/tests/close-watcher/dialog-cancel-preventDefault-closewatcher.html
deleted file mode 100644
index ef99578ca97..00000000000
--- a/tests/wpt/tests/close-watcher/dialog-cancel-preventDefault-closewatcher.html
+++ /dev/null
@@ -1,55 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <title>Test cancel event with preventDefault on cancel event for dialog element</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>
- <link rel="help" href="https://bugs.webkit.org/show_bug.cgi?id=227534">
- <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1322947">
-</head>
-<body>
-<p>Test cancel event with preventDefault on cancel event for dialog element</p>
-<dialog>
- <p>Hello World</p>
- <button>user activation button</button>
-</dialog>
-<script>
- setup({ single_test: true });
-
- var hasCancelEventFired = false;
-
- const dialog = document.querySelector("dialog");
-
- const verify = () => {
- assert_true(hasCancelEventFired, "cancel is fired");
- done();
- };
-
- dialog.addEventListener("cancel", function(event) {
- hasCancelEventFired = true;
- event.preventDefault();
- step_timeout(function() {
- verify();
- }, 0)
- });
-
- dialog.addEventListener("close", function() {
- assert_true(false, "close event should not be fired");
- });
-
- dialog.showModal();
-
- (async () => {
- // Pressing escape on the dialog needs user activation or else the cancel event won't be fired.
- const button = dialog.querySelector('button');
- const buttonClickPromise = new Promise(resolve => button.onclick = resolve);
- await test_driver.click(button);
- await buttonClickPromise;
-
- test_driver.send_keys(document.documentElement, "\uE00C"); // ESC key
- })();
-</script>
-</body>
-</html>
diff --git a/tests/wpt/tests/close-watcher/resources/helpers.js b/tests/wpt/tests/close-watcher/resources/helpers.js
index c4c8c5b0326..97a62309cd5 100644
--- a/tests/wpt/tests/close-watcher/resources/helpers.js
+++ b/tests/wpt/tests/close-watcher/resources/helpers.js
@@ -1,11 +1,11 @@
-window.createRecordingCloseWatcher = (t, events, name, type, parent) => {
+window.createRecordingCloseWatcher = (t, events, name, type, parentWatcher) => {
let watcher = null;
if (type === 'dialog') {
watcher = document.createElement('dialog');
watcher.textContent = 'hello world';
t.add_cleanup(() => watcher.remove());
- if (parent) {
- parent.appendChild(watcher);
+ if (parentWatcher?.appendChild) {
+ parentWatcher.appendChild(watcher);
} else {
document.body.appendChild(watcher);
}
@@ -15,8 +15,8 @@ window.createRecordingCloseWatcher = (t, events, name, type, parent) => {
watcher.setAttribute('popover', 'auto');
watcher.textContent = 'hello world';
t.add_cleanup(() => watcher.remove());
- if (parent) {
- parent.appendChild(watcher);
+ if (parentWatcher?.appendChild) {
+ parentWatcher.appendChild(watcher);
} else {
document.body.appendChild(watcher);
}
@@ -33,8 +33,9 @@ window.createRecordingCloseWatcher = (t, events, name, type, parent) => {
return watcher;
};
-window.createBlessedRecordingCloseWatcher = async (t, events, name, type, dialog) => {
- return dialogResilientBless(dialog, () => createRecordingCloseWatcher(t, events, name, type, dialog));
+window.createBlessedRecordingCloseWatcher = async (t, events, name, type, parentWatcher) => {
+ await maybeTopLayerBless(parentWatcher);
+ return createRecordingCloseWatcher(t, events, name, type, parentWatcher);
};
window.sendEscKey = () => {
@@ -52,20 +53,9 @@ window.sendEscKey = () => {
// function, but not update the sendEscKey function above.
window.sendCloseRequest = window.sendEscKey;
-// This function is a version of test_driver.bless which works on dialog elements:
-// https://github.com/web-platform-tests/wpt/issues/41218
-window.dialogResilientBless = async (watcher, fn) => {
+window.maybeTopLayerBless = (watcher) => {
if (watcher instanceof HTMLElement) {
- const button = document.createElement('button');
- watcher.appendChild(button);
- await test_driver.click(button);
- button.remove();
- if (typeof fn === 'function') {
- return fn();
- } else {
- return null;
- }
- } else {
- return await test_driver.bless('dialogResilientBless', fn);
+ return blessTopLayer(watcher);
}
+ return test_driver.bless();
};
diff --git a/tests/wpt/tests/close-watcher/user-activation-shared.html b/tests/wpt/tests/close-watcher/user-activation-shared.html
index 6ecc2dc694d..77e748532a3 100644
--- a/tests/wpt/tests/close-watcher/user-activation-shared.html
+++ b/tests/wpt/tests/close-watcher/user-activation-shared.html
@@ -6,6 +6,7 @@
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/resources/testdriver-actions.js"></script>
+<script src="/common/top-layer.js"></script>
<script src="resources/helpers.js"></script>
<body>
@@ -22,7 +23,8 @@ promise_test(async t => {
const freeWatcher = createRecordingCloseWatcher(t, events, "freeWatcher", type);
freeWatcher.addEventListener("cancel", e => e.preventDefault());
- await dialogResilientBless(freeWatcher, () => freeWatcher.close());
+ await maybeTopLayerBless(freeWatcher);
+ freeWatcher.close();
await waitForPotentialCloseEvent();
assert_array_equals(events, ["freeWatcher close"]);
@@ -32,7 +34,8 @@ promise_test(async t => {
const events = [];
const freeWatcher = createRecordingCloseWatcher(t, events, "freeWatcher", type);
- await dialogResilientBless(freeWatcher, () => sendCloseRequest());
+ await maybeTopLayerBless(freeWatcher);
+ await sendCloseRequest();
await waitForPotentialCloseEvent();
assert_array_equals(events, ["freeWatcher cancel", "freeWatcher close"]);
@@ -43,7 +46,8 @@ promise_test(async t => {
const freeWatcher = createRecordingCloseWatcher(t, events, "freeWatcher", type);
freeWatcher.addEventListener("cancel", e => e.preventDefault());
- await dialogResilientBless(freeWatcher, () => sendCloseRequest());
+ await maybeTopLayerBless(freeWatcher);
+ await sendCloseRequest();
await waitForPotentialCloseEvent();
assert_array_equals(events, ["freeWatcher cancel"]);
@@ -79,11 +83,13 @@ promise_test(async t => {
const freeWatcher = createRecordingCloseWatcher(t, events, "freeWatcher", type);
const activationWatcher = await createBlessedRecordingCloseWatcher(t, events, "activationWatcher", type, freeWatcher);
- await dialogResilientBless(activationWatcher, () => sendCloseRequest());
+ await maybeTopLayerBless(activationWatcher);
+ await sendCloseRequest();
await waitForPotentialCloseEvent();
assert_array_equals(events, ["activationWatcher cancel", "activationWatcher close"]);
- await dialogResilientBless(freeWatcher, () => sendCloseRequest());
+ await maybeTopLayerBless(freeWatcher);
+ await sendCloseRequest();
await waitForPotentialCloseEvent();
assert_array_equals(events, ["activationWatcher cancel", "activationWatcher close", "freeWatcher cancel", "freeWatcher close"]);
}, "Creating a close watcher from user activation, and closing close watchers with a close request after user activation, fires cancel");
diff --git a/tests/wpt/tests/common/top-layer.js b/tests/wpt/tests/common/top-layer.js
new file mode 100644
index 00000000000..2dc8ce3893a
--- /dev/null
+++ b/tests/wpt/tests/common/top-layer.js
@@ -0,0 +1,29 @@
+// This function is a version of test_driver.bless which works while there are
+// elements in the top layer:
+// https://github.com/web-platform-tests/wpt/issues/41218.
+// Pass it the element at the top of the top layer stack.
+window.blessTopLayer = async (topLayerElement) => {
+ const button = document.createElement('button');
+ topLayerElement.append(button);
+ let wait_click = new Promise(resolve => button.addEventListener("click", resolve, {once: true}));
+ await test_driver.click(button);
+ await wait_click;
+ button.remove();
+};
+
+window.isTopLayer = (el) => {
+ // A bit of a hack. Just test a few properties of the ::backdrop pseudo
+ // element that change when in the top layer.
+ const properties = ['right','background'];
+ const testEl = document.createElement('div');
+ document.body.appendChild(testEl);
+ const computedStyle = getComputedStyle(testEl, '::backdrop');
+ const nonTopLayerValues = properties.map(p => computedStyle[p]);
+ testEl.remove();
+ for(let i=0;i<properties.length;++i) {
+ if (getComputedStyle(el,'::backdrop')[properties[i]] !== nonTopLayerValues[i]) {
+ return true;
+ }
+ }
+ return false;
+};
diff --git a/tests/wpt/tests/content-security-policy/resource-hints/prefetch-generate-directives.html b/tests/wpt/tests/content-security-policy/resource-hints/prefetch-generate-directives.html
index b08d885c1ec..75c9485f0d7 100644
--- a/tests/wpt/tests/content-security-policy/resource-hints/prefetch-generate-directives.html
+++ b/tests/wpt/tests/content-security-policy/resource-hints/prefetch-generate-directives.html
@@ -1,6 +1,7 @@
<!DOCTYPE html>
<html>
<head>
+<meta name="timeout" content="long">
<script src='/resources/testharness.js'></script>
<script src='/resources/testharnessreport.js'></script>
<script src='/common/utils.js'></script>
diff --git a/tests/wpt/tests/credential-management/fedcm-hosteddomain.https.html b/tests/wpt/tests/credential-management/fedcm-domainhint.https.html
index 5e39542fdef..d8ab79b2c5c 100644
--- a/tests/wpt/tests/credential-management/fedcm-hosteddomain.https.html
+++ b/tests/wpt/tests/credential-management/fedcm-domainhint.https.html
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<title>Federated Credential Management API hosted domain tests.</title>
+<title>Federated Credential Management API domain hint tests.</title>
<link rel="help" href="https://fedidcg.github.io/FedCM">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
@@ -10,40 +10,40 @@
<script type="module">
import {
fedcm_test,
- request_options_with_hosted_domain,
+ request_options_with_domain_hint,
select_manifest,
fedcm_get_and_select_first_account
} from './support/fedcm-helper.sub.js';
fedcm_test(async t => {
- let options = request_options_with_hosted_domain('manifest.py',
+ let options = request_options_with_domain_hint('manifest.py',
'nomatch');
const cred = fedcm_get_and_select_first_account(t, options);
return promise_rejects_dom(t, "NetworkError", cred);
-}, "No hosted domain matches an account.");
+}, "No domain hint matches an account.");
fedcm_test(async t => {
- const options = request_options_with_hosted_domain('manifest.py',
+ const options = request_options_with_domain_hint('manifest.py',
'idp.example');
const cred = await fedcm_get_and_select_first_account(t, options);
assert_equals(cred.token, 'token');
-}, "Hosted domain matches an account.");
+}, "Domain hint matches an account.");
fedcm_test(async t => {
- let options = request_options_with_hosted_domain(
+ let options = request_options_with_domain_hint(
'manifest_with_two_accounts.json', 'example');
await select_manifest(t, options);
const cred = await fedcm_get_and_select_first_account(t, options);
assert_equals(cred.token, 'account_id=john_doe');
-}, "Hosted domain matches an account from two accounts.");
+}, "Domain hint matches an account from two accounts.");
fedcm_test(async t => {
- let options = request_options_with_hosted_domain(
+ let options = request_options_with_domain_hint(
'manifest_with_two_accounts.json', '*');
await select_manifest(t, options);
const cred = await fedcm_get_and_select_first_account(t, options);
assert_equals(cred.token, 'account_id=john_doe');
-}, "Hosted domain '*' matches an account with any hosted domain.");
+}, "Domain hint '*' matches an account with any domain hint.");
</script>
diff --git a/tests/wpt/tests/credential-management/fedcm-endpoint-redirects.https.html b/tests/wpt/tests/credential-management/fedcm-endpoint-redirects.https.html
index 4aebc17f1ba..21d0a5867a7 100644
--- a/tests/wpt/tests/credential-management/fedcm-endpoint-redirects.https.html
+++ b/tests/wpt/tests/credential-management/fedcm-endpoint-redirects.https.html
@@ -24,7 +24,13 @@ fedcm_test(async t => {
let test_options = request_options_with_mediation_required("manifest_redirect_token.json");
await select_manifest(t, test_options);
- const cred = fedcm_get_and_select_first_account(t, test_options);
- return promise_rejects_dom(t, 'NetworkError', cred);
+ try {
+ const cred = await fedcm_get_and_select_first_account(t, test_options);
+ assert_unreached("An IdentityCredentialError exception should be thrown.");
+ } catch (e) {
+ assert_true(e instanceof DOMException);
+ assert_equals(e.name, "IdentityCredentialError");
+ assert_equals(e.code, "server_error");
+ }
}, 'Test that token endpoint does not follow redirects');
</script>
diff --git a/tests/wpt/tests/credential-management/fedcm-error-basic.https.html b/tests/wpt/tests/credential-management/fedcm-error-basic.https.html
new file mode 100644
index 00000000000..18ab82d0bd7
--- /dev/null
+++ b/tests/wpt/tests/credential-management/fedcm-error-basic.https.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<title>Federated Credential Management API Error API tests.</title>
+<link rel="help" href="https://fedidcg.github.io/FedCM">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+
+<script type="module">
+import {request_options_with_mediation_required,
+ fedcm_test,
+ manifest_origin,
+ select_manifest,
+ fedcm_get_and_select_first_account} from './support/fedcm-helper.sub.js';
+
+const url_prefix = manifest_origin + '/credential-management/support/fedcm/';
+
+fedcm_test(async t => {
+ let test_options =
+ request_options_with_mediation_required("manifest_id_assertion_endpoint_returns_error.json");
+ await select_manifest(t, test_options);
+
+ try {
+ const cred = await fedcm_get_and_select_first_account(t, test_options);
+ assert_unreached("An IdentityCredentialError exception should be thrown.");
+ } catch (e) {
+ assert_true(e instanceof DOMException);
+ assert_equals(e.name, "IdentityCredentialError");
+ assert_equals(e.code, "unauthorized_client");
+ assert_equals(e.url, url_prefix + "error.html");
+ }
+}, 'Test that the promise is rejected with proper error details');
+
+</script>
diff --git a/tests/wpt/tests/credential-management/fedcm-login-status/cross-origin-status.https.html b/tests/wpt/tests/credential-management/fedcm-login-status/cross-origin-status.https.html
index 7c839306a47..09a4aa31c6b 100644
--- a/tests/wpt/tests/credential-management/fedcm-login-status/cross-origin-status.https.html
+++ b/tests/wpt/tests/credential-management/fedcm-login-status/cross-origin-status.https.html
@@ -10,6 +10,7 @@
import {fedcm_test,
alt_manifest_origin,
alt_request_options_with_mediation_required,
+ open_and_wait_for_popup,
mark_signed_out} from '../support/fedcm-helper.sub.js';
const url_prefix = alt_manifest_origin + '/credential-management/support/';
@@ -53,5 +54,14 @@ fedcm_test(async t => {
return promise_rejects_dom(t, 'NetworkError', result);
}, 'Status header should be ignored from cross-origin iframe that contains a subresource with the header');
+fedcm_test(async t => {
+ await mark_signed_out(alt_manifest_origin);
+ await open_and_wait_for_popup(alt_manifest_origin, "/credential-management/support/fencedframe-mark-signedin.html");
+
+ const config = alt_request_options_with_mediation_required();
+ const result = navigator.credentials.get(config);
+ return promise_rejects_dom(t, 'NetworkError', result);
+}, 'Status header should be ignored from a fenced frame, even if it is same-origin');
+
</script>
diff --git a/tests/wpt/tests/credential-management/fedcm-store.https.html b/tests/wpt/tests/credential-management/fedcm-store.https.html
new file mode 100644
index 00000000000..d1e6ef464c4
--- /dev/null
+++ b/tests/wpt/tests/credential-management/fedcm-store.https.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<title>Federated Credential Management API store() tests.</title>
+<link rel="help" href="https://fedidcg.github.io/FedCM">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+
+<script type="module">
+import {fedcm_test,
+ request_options_with_mediation_required,
+ fedcm_get_and_select_first_account} from "./support/fedcm-helper.sub.js";
+
+fedcm_test(async t => {
+ const cred = await fedcm_get_and_select_first_account(t, request_options_with_mediation_required());
+ return promise_rejects_dom(t, "NotSupportedError", navigator.credentials.store(cred));
+}, "navigator.credentials.store() with an identity credential returns NotSupportedError");
+
+</script>
diff --git a/tests/wpt/tests/credential-management/fedcm-token-returned-with-http-error.https.html b/tests/wpt/tests/credential-management/fedcm-token-returned-with-http-error.https.html
new file mode 100644
index 00000000000..2337829add9
--- /dev/null
+++ b/tests/wpt/tests/credential-management/fedcm-token-returned-with-http-error.https.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<title>Federated Credential Management API token response tests</title>
+<link rel="help" href="https://fedidcg.github.io/FedCM">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+
+<script type="module">
+import {request_options_with_mediation_required,
+ fedcm_test,
+ select_manifest,
+ fedcm_get_and_select_first_account} from './support/fedcm-helper.sub.js';
+
+fedcm_test(async t => {
+ const test_options =
+ request_options_with_mediation_required("manifest_token_with_http_error.json");
+ await select_manifest(t, test_options);
+
+ const cred = fedcm_get_and_select_first_account(t, test_options);
+ return promise_rejects_dom(t, 'NetworkError', cred);
+}, 'Test that the promise will be rejected if the response has http error');
+</script>
diff --git a/tests/wpt/tests/credential-management/otpcredential-store.https.html b/tests/wpt/tests/credential-management/otpcredential-store.https.html
new file mode 100644
index 00000000000..fa2ae8933d3
--- /dev/null
+++ b/tests/wpt/tests/credential-management/otpcredential-store.https.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<link rel="help" href="https://github.com/WICG/WebOTP">
+<title>Tests OTPCredential handing of store()</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script type="module">
+import {Status, expectOTPRequest} from "./support/otpcredential-helper.js";
+
+promise_test(async t => {
+ await expectOTPRequest().andReturn(
+ () => ({status: Status.SUCCESS, otp: "ABC"}));
+
+ const cred = await navigator.credentials.get({otp: {transport: ["sms"]}});
+ return promise_rejects_dom(t, "NotSupportedError", navigator.credentials.store(cred));
+}, "navigator.credentials.store() with an otp credential returns NotSupportedError");
+
+</script>
diff --git a/tests/wpt/tests/credential-management/support/fedcm-helper.sub.js b/tests/wpt/tests/credential-management/support/fedcm-helper.sub.js
index ef10e41793a..f02a76b3fe2 100644
--- a/tests/wpt/tests/credential-management/support/fedcm-helper.sub.js
+++ b/tests/wpt/tests/credential-management/support/fedcm-helper.sub.js
@@ -1,31 +1,31 @@
-const manifest_origin = "https://{{host}}:{{ports[https][0]}}";
+export const manifest_origin = "https://{{host}}:{{ports[https][0]}}";
export const alt_manifest_origin = 'https://{{hosts[alt][]}}:{{ports[https][0]}}';
-function open_and_wait_for_popup(origin, path, resolve) {
- let popup_window = window.open(origin + path);
+export function open_and_wait_for_popup(origin, path) {
+ return new Promise(resolve => {
+ let popup_window = window.open(origin + path);
- // We rely on the popup page to send us a message when done.
- const popup_message_handler = (event) => {
- if (event.origin == origin) {
- popup_window.close();
- window.removeEventListener('message', popup_message_handler);
- resolve();
- }
- };
+ // We rely on the popup page to send us a message when done.
+ const popup_message_handler = (event) => {
+ if (event.origin == origin) {
+ popup_window.close();
+ window.removeEventListener('message', popup_message_handler);
+ resolve();
+ }
+ };
- window.addEventListener('message', popup_message_handler);
+ window.addEventListener('message', popup_message_handler);
+ });
}
// Set the identity provider cookie.
export function set_fedcm_cookie(host) {
- return new Promise(resolve => {
- if (host == undefined) {
- document.cookie = 'cookie=1; SameSite=Strict; Path=/credential-management/support; Secure';
- resolve();
- } else {
- open_and_wait_for_popup(host, '/credential-management/support/set_cookie', resolve);
- }
- });
+ if (host == undefined) {
+ document.cookie = 'cookie=1; SameSite=Strict; Path=/credential-management/support; Secure';
+ return Promise.resolve();
+ } else {
+ return open_and_wait_for_popup(host, '/credential-management/support/set_cookie');
+ }
}
// Set the alternate identity provider cookie.
@@ -34,15 +34,11 @@ export function set_alt_fedcm_cookie() {
}
export function mark_signed_in(origin = manifest_origin) {
- return new Promise(resolve => {
- open_and_wait_for_popup(origin, '/credential-management/support/mark_signedin', resolve);
- });
+ return open_and_wait_for_popup(origin, '/credential-management/support/mark_signedin');
}
export function mark_signed_out(origin = manifest_origin) {
- return new Promise(resolve => {
- open_and_wait_for_popup(origin, '/credential-management/support/mark_signedout', resolve);
- });
+ return open_and_wait_for_popup(origin, '/credential-management/support/mark_signedout');
}
// Returns FedCM CredentialRequestOptions for which navigator.credentials.get()
@@ -156,9 +152,9 @@ export function request_options_with_login_hint(manifest_filename, login_hint) {
return options;
}
-export function request_options_with_hosted_domain(manifest_filename, hosted_domain) {
+export function request_options_with_domain_hint(manifest_filename, domain_hint) {
let options = request_options_with_mediation_required(manifest_filename);
- options.identity.providers[0].hostedDomain = hosted_domain;
+ options.identity.providers[0].domainHint = domain_hint;
return options;
}
diff --git a/tests/wpt/tests/credential-management/support/fedcm-mock.js b/tests/wpt/tests/credential-management/support/fedcm-mock.js
index 16a72b1d2c3..b14bbaa80a7 100644
--- a/tests/wpt/tests/credential-management/support/fedcm-mock.js
+++ b/tests/wpt/tests/credential-management/support/fedcm-mock.js
@@ -1,4 +1,4 @@
-import { RequestTokenStatus, LogoutRpsStatus, FederatedAuthRequest, FederatedAuthRequestReceiver } from '/gen/third_party/blink/public/mojom/webid/federated_auth_request.mojom.m.js';
+import { RequestTokenStatus, LogoutRpsStatus, RevokeStatus, FederatedAuthRequest, FederatedAuthRequestReceiver } from '/gen/third_party/blink/public/mojom/webid/federated_auth_request.mojom.m.js';
function toMojoTokenStatus(status) {
return RequestTokenStatus["k" + status];
@@ -17,6 +17,7 @@ export class MockFederatedAuthRequest {
this.selected_identity_provider_config_url_ = null;
this.status_ = RequestTokenStatus.kError;
this.logoutRpsStatus_ = LogoutRpsStatus.kError;
+ this.revokeStatus_ = RevokeStatus.kError;
this.returnPending_ = false;
this.pendingPromiseResolve_ = null;
}
@@ -52,6 +53,15 @@ export class MockFederatedAuthRequest {
this.logoutRpsStatus_ = validated;
}
+ // Causes the subsequent `FederatedCredential.revoke` to reject with this
+ // status.
+ revokeReturn(status) {
+ let validated = RevokeStatus[status];
+ if (validated === undefined)
+ throw new Error("Invalid status: " + status);
+ this.revokeStatus_ = validated;
+ }
+
// Implements
// RequestToken(array<IdentityProviderGetParameters> idp_get_params) =>
// (RequestTokenStatus status,
@@ -96,6 +106,12 @@ export class MockFederatedAuthRequest {
});
}
+ async revoke(provider, client_id, account_id) {
+ return Promise.resolve({
+ status: this.revokeStatus_
+ });
+ }
+
async setIdpSigninStatus(origin, status) {
}
@@ -119,6 +135,7 @@ export class MockFederatedAuthRequest {
this.selected_identity_provider_config_url_ = null;
this.status_ = RequestTokenStatus.kError;
this.logoutRpsStatus_ = LogoutRpsStatus.kError;
+ this.revokeStatus_ = RevokeStatus.kError;
this.receiver_.$.close();
this.interceptor_.stop();
diff --git a/tests/wpt/tests/credential-management/support/fedcm/accounts.py b/tests/wpt/tests/credential-management/support/fedcm/accounts.py
index 3989de7f17c..126f911a58c 100644
--- a/tests/wpt/tests/credential-management/support/fedcm/accounts.py
+++ b/tests/wpt/tests/credential-management/support/fedcm/accounts.py
@@ -18,7 +18,7 @@ def main(request, response):
"picture": "https://idp.example/profile/123",
"approved_clients": ["123", "456", "789"],
"login_hints": ["john_doe"],
- "hosted_domains": ["idp.example", "example"]
+ "domain_hints": ["idp.example", "example"]
}]
}
"""
diff --git a/tests/wpt/tests/credential-management/support/fedcm/error_with_code_and_url.py b/tests/wpt/tests/credential-management/support/fedcm/error_with_code_and_url.py
new file mode 100644
index 00000000000..71bfea00f46
--- /dev/null
+++ b/tests/wpt/tests/credential-management/support/fedcm/error_with_code_and_url.py
@@ -0,0 +1,12 @@
+import importlib
+error_checker = importlib.import_module("credential-management.support.fedcm.request-params-check")
+
+def main(request, response):
+ request_error = error_checker.tokenCheck(request)
+ if (request_error):
+ return request_error
+
+ response.headers.set(b"Content-Type", b"application/json")
+ response.status = (401, b"Unauthorized")
+
+ return "{\"error\": {\"code\": \"unauthorized_client\", \"url\": \"error.html\"}}"
diff --git a/tests/wpt/tests/credential-management/support/fedcm/manifest_id_assertion_endpoint_returns_error.json b/tests/wpt/tests/credential-management/support/fedcm/manifest_id_assertion_endpoint_returns_error.json
new file mode 100644
index 00000000000..e098cc4511a
--- /dev/null
+++ b/tests/wpt/tests/credential-management/support/fedcm/manifest_id_assertion_endpoint_returns_error.json
@@ -0,0 +1,6 @@
+{
+ "accounts_endpoint": "accounts.py",
+ "client_metadata_endpoint": "client_metadata.py",
+ "id_assertion_endpoint": "error_with_code_and_url.py",
+ "login_url": "login.html"
+}
diff --git a/tests/wpt/tests/credential-management/support/fedcm/manifest_token_with_http_error.json b/tests/wpt/tests/credential-management/support/fedcm/manifest_token_with_http_error.json
new file mode 100644
index 00000000000..691a1e8d3a6
--- /dev/null
+++ b/tests/wpt/tests/credential-management/support/fedcm/manifest_token_with_http_error.json
@@ -0,0 +1,6 @@
+{
+ "accounts_endpoint": "accounts.py",
+ "client_metadata_endpoint": "client_metadata.py",
+ "id_assertion_endpoint": "token_with_http_error.py",
+ "login_url": "login.html"
+}
diff --git a/tests/wpt/tests/credential-management/support/fedcm/token_with_http_error.py b/tests/wpt/tests/credential-management/support/fedcm/token_with_http_error.py
new file mode 100644
index 00000000000..c8d95ab63d7
--- /dev/null
+++ b/tests/wpt/tests/credential-management/support/fedcm/token_with_http_error.py
@@ -0,0 +1,12 @@
+import importlib
+error_checker = importlib.import_module("credential-management.support.fedcm.request-params-check")
+
+def main(request, response):
+ request_error = error_checker.tokenCheck(request)
+ if (request_error):
+ return request_error
+
+ response.headers.set(b"Content-Type", b"application/json")
+ response.status = (403, b"Forbidden")
+
+ return "{\"token\": \"token\"}"
diff --git a/tests/wpt/tests/credential-management/support/fedcm/two_accounts.py b/tests/wpt/tests/credential-management/support/fedcm/two_accounts.py
index 4ea6d76a7eb..4022561ff78 100644
--- a/tests/wpt/tests/credential-management/support/fedcm/two_accounts.py
+++ b/tests/wpt/tests/credential-management/support/fedcm/two_accounts.py
@@ -27,7 +27,7 @@ def main(request, response):
"picture": "https://idp.example/profile/123",
"approved_clients": ["123", "456", "789"],
"login_hints": ["john_doe"],
- "hosted_domains": ["idp.example", "example"]
+ "domain_hints": ["idp.example", "example"]
}
]
}
diff --git a/tests/wpt/tests/credential-management/support/fencedframe-mark-signedin.html b/tests/wpt/tests/credential-management/support/fencedframe-mark-signedin.html
new file mode 100644
index 00000000000..532db7047a8
--- /dev/null
+++ b/tests/wpt/tests/credential-management/support/fencedframe-mark-signedin.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<title>A page that uses fencedframe to set the login status to signed in</title>
+
+<fencedframe></fencedframe>
+<script>
+const url = new URL("mark_signedin", location.href);
+document.querySelector("fencedframe").config = new FencedFrameConfig(url);
+
+// If this page was opened as a popup, notify the opener when we are done loading.
+if (window.opener) {
+ window.onload = function() {
+ window.opener.postMessage("done_loading", "*");
+ };
+}
+</script>
diff --git a/tests/wpt/tests/credential-management/support/iframe-mark-signedin.html b/tests/wpt/tests/credential-management/support/iframe-mark-signedin.html
new file mode 100644
index 00000000000..4ca0125cde2
--- /dev/null
+++ b/tests/wpt/tests/credential-management/support/iframe-mark-signedin.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<title>A page that includes mark_signedin, for use in an iframe</title>
+
+<img src="mark_signedin">
diff --git a/tests/wpt/tests/credential-management/support/mark_signedin.sub.headers b/tests/wpt/tests/credential-management/support/mark_signedin.sub.headers
index b87b36fa3b3..d560fade5a0 100644
--- a/tests/wpt/tests/credential-management/support/mark_signedin.sub.headers
+++ b/tests/wpt/tests/credential-management/support/mark_signedin.sub.headers
@@ -2,3 +2,4 @@ Content-Type: text/html
Set-Login: logged-in
Access-Control-Allow-Origin: https://{{host}}:{{ports[https][0]}}
Access-Control-Allow-Credentials: true
+Supports-Loading-Mode: fenced-frame
diff --git a/tests/wpt/tests/credential-management/support/mark_signedout.sub.headers b/tests/wpt/tests/credential-management/support/mark_signedout.sub.headers
index 46a8c34b218..69157b3a371 100644
--- a/tests/wpt/tests/credential-management/support/mark_signedout.sub.headers
+++ b/tests/wpt/tests/credential-management/support/mark_signedout.sub.headers
@@ -2,3 +2,4 @@ Content-Type: text/html
Set-Login: logged-out
Access-Control-Allow-Origin: https://{{host}}:{{ports[https][0]}}
Access-Control-Allow-Credentials: true
+Supports-Loading-Mode: fenced-frame
diff --git a/tests/wpt/tests/css/css-color/lch-009.html b/tests/wpt/tests/css/css-color/lch-009.html
index 472e7c138f7..375fd08de58 100644
--- a/tests/wpt/tests/css/css-color/lch-009.html
+++ b/tests/wpt/tests/css/css-color/lch-009.html
@@ -7,10 +7,10 @@
<meta name="assert" content="lch() with no alpha">
<style>
body { background-color: grey; }
- .test { background-color: hsl(47, 100%, 63%); width: 12em; height: 12em; }
+ .test { background-color: hsl(0, 100%, 63%); width: 12em; height: 12em; }
.test { background-color: lch(100% 110 60); } /* l = 100% should always be white */
</style>
<body>
- <p>Test passes if you see a white square, and no yellow.</p>
+ <p>Test passes if you see a white square, and no red.</p>
<div class="test"></div>
</body>
diff --git a/tests/wpt/tests/css/css-color/lch-010.html b/tests/wpt/tests/css/css-color/lch-010.html
index 527e9cc7aff..965e05ff5dc 100644
--- a/tests/wpt/tests/css/css-color/lch-010.html
+++ b/tests/wpt/tests/css/css-color/lch-010.html
@@ -6,10 +6,10 @@
<link rel="match" href="blacksquare-ref.html">
<meta name="assert" content="lch() with no alpha">
<style>
- .test { background-color: hsl(360, 100%, 15%); width: 12em; height: 12em; }
+ .test { background-color: hsl(0, 100%, 63%); width: 12em; height: 12em; }
.test { background-color: lch(0% 110 60); } /* l = 0% should always be black */
</style>
<body>
- <p>Test passes if you see a black square, and no dark red.</p>
+ <p>Test passes if you see a black square, and no red.</p>
<div class="test"></div>
</body>
diff --git a/tests/wpt/tests/css/css-color/nested-color-mix-with-currentcolor.html b/tests/wpt/tests/css/css-color/nested-color-mix-with-currentcolor.html
index a4dd687dd58..2f24d62b547 100644
--- a/tests/wpt/tests/css/css-color/nested-color-mix-with-currentcolor.html
+++ b/tests/wpt/tests/css/css-color/nested-color-mix-with-currentcolor.html
@@ -19,6 +19,6 @@
</div>
<script>
test(() => {
- assert_equals(getComputedStyle(child).backgroundColor, "lch(0 0 0)");
+ assert_equals(getComputedStyle(child).backgroundColor, "lch(0 0 none)");
}, "Nested color-mix function with inner currentColor should inherit unresolved");
</script>
diff --git a/tests/wpt/tests/css/css-color/oklch-009.html b/tests/wpt/tests/css/css-color/oklch-009.html
index 5a4924a7e28..1882c476c1c 100644
--- a/tests/wpt/tests/css/css-color/oklch-009.html
+++ b/tests/wpt/tests/css/css-color/oklch-009.html
@@ -8,10 +8,10 @@
<meta name="assert" content="oklch() with no alpha">
<style>
body { background-color: grey; }
- .test { background-color: hsl(120, 100%, 50%); width: 12em; height: 12em; }
+ .test { background-color: hsl(0, 100%, 50%); width: 12em; height: 12em; }
.test { background-color: oklch(100% 110 60); } /* l = 100% should always be white */
</style>
<body>
- <p>Test passes if you see a white square, and no green.</p>
+ <p>Test passes if you see a white square, and no red.</p>
<div class="test"></div>
</body>
diff --git a/tests/wpt/tests/css/css-color/oklch-010.html b/tests/wpt/tests/css/css-color/oklch-010.html
index 091b760bea2..b5f9ac206b4 100644
--- a/tests/wpt/tests/css/css-color/oklch-010.html
+++ b/tests/wpt/tests/css/css-color/oklch-010.html
@@ -7,10 +7,10 @@
<link rel="match" href="blacksquare-ref.html">
<meta name="assert" content="oklch() with no alpha">
<style>
- .test { background-color: hsl(120, 100%, 50%); width: 12em; height: 12em; }
+ .test { background-color: hsl(0, 100%, 50%); width: 12em; height: 12em; }
.test { background-color: oklch(0% 1.1 60); } /* l = 0% should always be black */
</style>
<body>
- <p>Test passes if you see a black square, and no green.</p>
+ <p>Test passes if you see a black square, and no red.</p>
<div class="test"></div>
</body>
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 a48d6b20bcd..cd5837d8b28 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
@@ -77,7 +77,7 @@
fuzzy_test_computed_color(`color-mix(in hsl decreasing hue, hsl(20deg 50% 50%), hsl(320deg 50% 50%))`, `color(srgb 0.75 0.25 0.333333)`);
fuzzy_test_computed_color(`color-mix(in hsl decreasing hue, hsl(320deg 50% 50%), hsl(20deg 50% 50%))`, `color(srgb 0.25 0.75 0.666667)`);
- fuzzy_test_computed_color(`color-mix(in hsl, hsl(none none none), hsl(none none none))`, `color(srgb none none none)`);
+ fuzzy_test_computed_color(`color-mix(in hsl, hsl(none none none), hsl(none none none))`, `color(srgb 0 0 0)`);
fuzzy_test_computed_color(`color-mix(in hsl, hsl(none none none), hsl(30deg 40% 80%))`, `color(srgb 0.88 0.8 0.72)`);
fuzzy_test_computed_color(`color-mix(in hsl, hsl(120deg 20% 40%), hsl(none none none))`, `color(srgb 0.32 0.48 0.32)`);
fuzzy_test_computed_color(`color-mix(in hsl, hsl(120deg 20% none), hsl(30deg 40% 60%))`, `color(srgb 0.66 0.72 0.48)`);
@@ -149,7 +149,7 @@
fuzzy_test_computed_color(`color-mix(in hwb decreasing hue, hwb(20deg 30% 40%), hwb(320deg 30% 40%))`, `color(srgb 0.6 0.3 0.35)`);
fuzzy_test_computed_color(`color-mix(in hwb decreasing hue, hwb(320deg 30% 40%), hwb(20deg 30% 40%))`, `color(srgb 0.3 0.6 0.55)`);
- fuzzy_test_computed_color(`color-mix(in hwb, hwb(none none none), hwb(none none none))`, `color(srgb none none none)`);
+ fuzzy_test_computed_color(`color-mix(in hwb, hwb(none none none), hwb(none none none))`, `color(srgb 1 0 0)`);
fuzzy_test_computed_color(`color-mix(in hwb, hwb(none none none), hwb(30deg 30% 40%))`, `color(srgb 0.6 0.45 0.3)`);
fuzzy_test_computed_color(`color-mix(in hwb, hwb(120deg 10% 20%), hwb(none none none))`, `color(srgb 0.1 0.8 0.1)`);
fuzzy_test_computed_color(`color-mix(in hwb, hwb(120deg 10% none), hwb(30deg 30% 40%))`, `color(srgb 0.5 0.6 0.2)`);
diff --git a/tests/wpt/tests/css/css-color/system-color-support.html b/tests/wpt/tests/css/css-color/system-color-support.html
new file mode 100644
index 00000000000..a17ab6ab6ee
--- /dev/null
+++ b/tests/wpt/tests/css/css-color/system-color-support.html
@@ -0,0 +1,74 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+ <meta charset="utf-8">
+ <title>CSS Color 4: System color support</title>
+ <link rel="author" title="Luuk Lamers" href="mailto:xaddict@protonmail.com">
+ <link rel="help" href="https://www.w3.org/TR/css-color-4/#css-system-colors">
+ <meta name="assert" content="system colors as defined are supported by the browser">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <style>
+ .group {
+ display: flex;
+ margin-bottom: 2px;
+ gap: 1em;
+ }
+ .group > div {
+ height: 1em;
+ width: 50%;
+ }
+ </style>
+</head>
+<body>
+ <div style="display: none">
+ <div id="test"></div>
+ </div>
+ <script>
+ const testRoot = document.getElementById('test')
+ const systemColors = [
+ 'Canvas',
+ 'CanvasText',
+ 'LinkText',
+ 'VisitedText',
+ 'ActiveText',
+ 'ButtonFace',
+ 'ButtonText',
+ 'ButtonBorder',
+ 'Field',
+ 'FieldText',
+ 'Highlight',
+ 'HighlightText',
+ 'SelectedItem',
+ 'SelectedItemText',
+ 'Mark',
+ 'MarkText',
+ 'GrayText',
+ 'AccentColor',
+ 'AccentColorText'
+ ]
+
+ systemColors.forEach(systemColor => {
+ const testGroup = document.createElement('div')
+ testGroup.id = systemColor
+ testGroup.className = 'group'
+ testGroup.innerHTML = `
+ <div style="background-color: black; background-color: ${systemColor}"></div>
+ <div style="background-color: white; background-color: ${systemColor}"></div>`
+ testRoot.appendChild(testGroup)
+ })
+
+ systemColors.forEach(systemColor => {
+ let group = document.getElementById(systemColor)
+ let blackElement = group.firstElementChild
+ let whiteElement = group.lastElementChild
+ test(function() {
+ let blackValue = getComputedStyle(blackElement).getPropertyValue('background-color');
+ let whiteValue = getComputedStyle(whiteElement).getPropertyValue('background-color');
+ assert_equals(blackValue, whiteValue);
+ }, `System color ${systemColor} works`);
+ })
+ </script>
+</body>
+</html>
diff --git a/tests/wpt/tests/css/css-color/t32-opacity-basic-0.6-a-ref.html b/tests/wpt/tests/css/css-color/t32-opacity-basic-0.6-a-ref.html
deleted file mode 100644
index fb906237b23..00000000000
--- a/tests/wpt/tests/css/css-color/t32-opacity-basic-0.6-a-ref.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<!DOCTYPE html>
-<meta charset="utf-8">
-<title>CSS Reference</title>
-<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
-<style>
- .test { font-family: Ahem; color: rgb(102, 102, 102); }
-</style>
-<body>
- <p>The test passes if the two lines below look identical:</p>
- <p class="test">This text should be the same color as the line below.</p>
- <p class="test">This text should be the same color as the line above.</p>
-</body>
diff --git a/tests/wpt/tests/css/css-color/t32-opacity-basic-0.6-a-ref.xht b/tests/wpt/tests/css/css-color/t32-opacity-basic-0.6-a-ref.xht
new file mode 100644
index 00000000000..ae463485065
--- /dev/null
+++ b/tests/wpt/tests/css/css-color/t32-opacity-basic-0.6-a-ref.xht
@@ -0,0 +1,18 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title>CSS Test: rgba() colors</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/" />
+ <link rel="author" title="Chris Lilley" href="https://svgees.us" />
+ <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" />
+ <style type="text/css"><![CDATA[
+ html, body { background: white; color: black; }
+ #one, #two { width: 12em; height: 12em; }
+ #one { background-color: rgb(102, 102, 102); margin-bottom: 0 }
+ ]]></style>
+ </head>
+ <body>
+ <p>The test passes if you see a gray square:</p>
+ <p id="one"></p>
+ </body>
+</html>
diff --git a/tests/wpt/tests/css/css-color/t32-opacity-basic-0.6-a.xht b/tests/wpt/tests/css/css-color/t32-opacity-basic-0.6-a.xht
index 3687d5392e3..541964f8d61 100644
--- a/tests/wpt/tests/css/css-color/t32-opacity-basic-0.6-a.xht
+++ b/tests/wpt/tests/css/css-color/t32-opacity-basic-0.6-a.xht
@@ -6,19 +6,18 @@
<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" />
<link rel="help" href="http://www.w3.org/TR/css3-color/#transparency" />
<link rel="help" href="http://www.w3.org/TR/css3-color/#rgb-color" />
- <link rel="match" href="t32-opacity-basic-0.6-a-ref.html" />
- <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+ <link rel="match" href="t32-opacity-basic-0.6-a-ref.xht" />
<meta name="assert" content="Opacity of 0.6 makes box partially opaque. Colors are in sRGB color space (may test)." />
<style type="text/css"><![CDATA[
html, body { background: white; color: black; }
- #one, #two { font-family: Ahem; }
- #one { color: rgb(102, 102, 102); }
+ #one, #two { width: 12em; height: 12em; }
+ #one { background-color: rgb(102, 102, 102); }
#two { opacity: 0.6; }
]]></style>
</head>
<body>
- <p>The test passes if the two lines below look identical:</p>
- <p id="one">This text should be the same color as the line below.</p>
- <p id="two">This text should be the same color as the line above.</p>
+ <p>The test passes if you see a gray square:</p>
+ <p id="one"></p>
+ <p id="two"></p>
</body>
</html>
diff --git a/tests/wpt/tests/css/css-color/t422-rgba-a0.6-a-ref.xht b/tests/wpt/tests/css/css-color/t422-rgba-a0.6-a-ref.xht
new file mode 100644
index 00000000000..ae463485065
--- /dev/null
+++ b/tests/wpt/tests/css/css-color/t422-rgba-a0.6-a-ref.xht
@@ -0,0 +1,18 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title>CSS Test: rgba() colors</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/" />
+ <link rel="author" title="Chris Lilley" href="https://svgees.us" />
+ <link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" />
+ <style type="text/css"><![CDATA[
+ html, body { background: white; color: black; }
+ #one, #two { width: 12em; height: 12em; }
+ #one { background-color: rgb(102, 102, 102); margin-bottom: 0 }
+ ]]></style>
+ </head>
+ <body>
+ <p>The test passes if you see a gray square:</p>
+ <p id="one"></p>
+ </body>
+</html>
diff --git a/tests/wpt/tests/css/css-color/t422-rgba-a0.6-a.xht b/tests/wpt/tests/css/css-color/t422-rgba-a0.6-a.xht
index 2274eb3c312..a710a0b6251 100644
--- a/tests/wpt/tests/css/css-color/t422-rgba-a0.6-a.xht
+++ b/tests/wpt/tests/css/css-color/t422-rgba-a0.6-a.xht
@@ -3,22 +3,22 @@
<head>
<title>CSS Test: rgba() colors</title>
<link rel="author" title="L. David Baron" href="https://dbaron.org/" />
+ <link rel="author" title="Chris Lilley" href="https://svgees.us" />
<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" />
<link rel="help" href="http://www.w3.org/TR/css3-color/#rgba-color" />
<link rel="help" href="http://www.w3.org/TR/css3-color/#rgb-color" />
- <link rel="match" href="t32-opacity-basic-0.6-a-ref.html" />
- <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
- <meta name="assert" content="Opacity of 0.6 makes text partially opaque. Colors are in sRGB color space (may test)." />
+ <link rel="match" href="t422-rgba-a0.6-a-ref.xht" />
+ <meta name="assert" content="Opacity of 0.6 makes background partially opaque. Colors are in sRGB color space (may test)." />
<style type="text/css"><![CDATA[
html, body { background: white; color: black; }
- #one, #two { font-family: Ahem; }
- #one { color: rgb(102, 102, 102); }
- #two { color: rgba(0, 0, 0, 0.6); }
+ #one, #two { width: 12em; height: 6em; }
+ #one { background-color: rgb(102, 102, 102); margin-bottom: 0 }
+ #two { background-color: rgba(0, 0, 0, 0.6); margin-top:0 }
]]></style>
</head>
<body>
- <p>The test passes if the two lines below look identical:</p>
- <p id="one">This text should be the same color as the line below.</p>
- <p id="two">This text should be the same color as the line above.</p>
+ <p>The test passes if you see a gray square:</p>
+ <p id="one"></p>
+ <p id="two"></p>
</body>
</html>
diff --git a/tests/wpt/tests/css/css-color/t425-hsla-basic-a-ref.html b/tests/wpt/tests/css/css-color/t425-hsla-basic-a-ref.html
deleted file mode 100644
index 32eb4cd46cc..00000000000
--- a/tests/wpt/tests/css/css-color/t425-hsla-basic-a-ref.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!DOCTYPE html>
-<meta charset="utf-8">
-<title>CSS Reference</title>
-<style>
- div { width: 600px; height: 30px; margin-bottom: 10px; background-color: #66FF66; }
-</style>
-<body>
- <p>Test passes if the two boxes below are the same color.</p>
- <div></div>
- <div></div>
-</body>
diff --git a/tests/wpt/tests/css/css-color/t425-hsla-basic-a-ref.xht b/tests/wpt/tests/css/css-color/t425-hsla-basic-a-ref.xht
new file mode 100644
index 00000000000..bc21fe36a26
--- /dev/null
+++ b/tests/wpt/tests/css/css-color/t425-hsla-basic-a-ref.xht
@@ -0,0 +1,17 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title>CSS Test: hsla()</title>
+ <link rel="author" title="L. David Baron" href="https://dbaron.org/" />
+ <link rel="author" title="Chris Lilley" href="https://svgees.us" />
+ <style type="text/css"><![CDATA[
+ html, body { background: white; }
+ div { width: 12em; height: 12em; }
+ #one { background-color: hsla(120, 100%, 70%, 1.0); margin-bottom: 0 }
+ ]]></style>
+ </head>
+ <body>
+ <p>Test passes if you see a light green square.</p>
+ <div id="one"></div>
+ </body>
+</html>
diff --git a/tests/wpt/tests/css/css-color/t425-hsla-basic-a.xht b/tests/wpt/tests/css/css-color/t425-hsla-basic-a.xht
index 3645a9acedf..435041b5fa9 100644
--- a/tests/wpt/tests/css/css-color/t425-hsla-basic-a.xht
+++ b/tests/wpt/tests/css/css-color/t425-hsla-basic-a.xht
@@ -3,19 +3,29 @@
<head>
<title>CSS Test: hsla()</title>
<link rel="author" title="L. David Baron" href="https://dbaron.org/" />
+ <link rel="author" title="Chris Lilley" href="https://svgees.us" />
<link rel="author" title="Mozilla Corporation" href="http://mozilla.com/" />
<link rel="help" href="http://www.w3.org/TR/css3-color/#hsla-color" />
- <link rel="match" href="t425-hsla-basic-a-ref.html" />
+ <link rel="match" href="t425-hsla-basic-a-ref.xht" />
<meta name="assert" content="Test basic functioning of hsla() colors." />
<style type="text/css"><![CDATA[
html, body { background: white; }
- div { width: 600px; height: 30px; margin-bottom: 10px; }
- #one { background-color: hsla(120, 100%, 70%, 1.0); }
- #two { background-color: hsla(120, 100%, 50%, 0.6); }
+ div { width: 12em; height: 6em; }
+ #one { background-color: hsla(120, 100%, 70%, 1.0); margin-bottom: 0 }
+ #two { background-color: hsla(120, 100%, 50%, 0.6); margin-top:0 }
]]></style>
+ /*
+ hsla(120, 100%, 70%, 1.0) is rgb(40% 100% 40%)
+ hsla(120, 100%, 50%, 0.6) is rgb(0% 100% 0% / 0.6)
+ composite rgb values at 60% over white in sRGB = rgb(40% 100% 40%)
+ BUT if compositing is done with used values, in device RGB
+ you will get a mismatch on WCG screen
+ because the red and blue components will not be zero
+ and the green will not be 100%
+ */
</head>
<body>
- <p>Test passes if the two boxes below are the same color.</p>
+ <p>Test passes if you see a light green square.</p>
<div id="one"></div>
<div id="two"></div>
</body>
diff --git a/tests/wpt/tests/css/css-color/xyz-d50-003-ref.html b/tests/wpt/tests/css/css-color/xyz-d50-003-ref.html
index 51f565e04b1..4223a511df5 100644
--- a/tests/wpt/tests/css/css-color/xyz-d50-003-ref.html
+++ b/tests/wpt/tests/css/css-color/xyz-d50-003-ref.html
@@ -3,7 +3,7 @@
<title>CSS Color 4: CSS Color 4: xyz-d50</title>
<style>
body { background-color: grey; }
- .test { background-color: lab(100% 6.1097 -13.2268); width: 12em; height: 12em; } /* color(xyz-d50 1 1 1) converted to Lab */
+ .test { background-color: color(srgb 1.01139 0.987129 1.10222); width: 12em; height: 12em; } /* color(xyz-d50 1 1 1) converted to srgb*/
</style>
<body>
<p>Test passes if you see a single square, and not two rectangles of different colors.</p>
diff --git a/tests/wpt/tests/css/css-color/xyz-d50-003.html b/tests/wpt/tests/css/css-color/xyz-d50-003.html
index 036bcb6c148..76301151874 100644
--- a/tests/wpt/tests/css/css-color/xyz-d50-003.html
+++ b/tests/wpt/tests/css/css-color/xyz-d50-003.html
@@ -8,7 +8,7 @@
<style>
body { background-color: grey; }
.test { background-color: red; width: 12em; height: 6em; margin-top: 0; }
- .ref { background-color: lab(100% 6.1097 -13.2268); width: 12em; height: 6em; margin-bottom: 0; } /* color(xyz-d50 1 1 1) converted to Lab */
+ .ref { background-color: color(srgb 1.01139 0.987129 1.10222); width: 12em; height: 6em; margin-bottom: 0; } /* color(xyz-d50 1 1 1) converted to sRGB */
.test { background-color: color(xyz-d50 1 1 1); }
</style>
<body>
diff --git a/tests/wpt/tests/css/css-color/xyz-d50-004-ref.html b/tests/wpt/tests/css/css-color/xyz-d50-004-ref.html
index 9d211ae42a5..4d1c08f2ae8 100644
--- a/tests/wpt/tests/css/css-color/xyz-d50-004-ref.html
+++ b/tests/wpt/tests/css/css-color/xyz-d50-004-ref.html
@@ -2,7 +2,7 @@
<meta charset="utf-8">
<title>CSS Color 4: CSS Color 4: xyz-d50</title>
<style>
- .test { background-color: lab(100% -431.0345 172.4138); width: 12em; height: 12em; } /* color(xyz-d50 0 1 0) converted to Lab */
+ .test { background-color: color(srgb -1.20716 1.3163 -0.489014); width: 12em; height: 12em; } /* color(xyz-d50 0 1 0) converted to srgb */
</style>
<body>
<p>Test passes if you see a single square, and not two rectangles of different colors.</p>
diff --git a/tests/wpt/tests/css/css-color/xyz-d50-004.html b/tests/wpt/tests/css/css-color/xyz-d50-004.html
index cc178590eae..f4aa9a0a1d5 100644
--- a/tests/wpt/tests/css/css-color/xyz-d50-004.html
+++ b/tests/wpt/tests/css/css-color/xyz-d50-004.html
@@ -7,7 +7,7 @@
<meta name="assert" content="xyz-d50 with no alpha">
<style>
.test { background-color: red; width: 12em; height: 6em; margin-top: 0; }
- .ref { background-color: lab(100% -431.0345 172.4138); width: 12em; height: 6em; margin-bottom: 0; } /* color(xyz-d50 0 1 0) converted to Lab */
+ .ref { background-color: color(srgb -1.20716 1.3163 -0.489014); width: 12em; height: 6em; margin-bottom: 0; } /* color(xyz-d50 0 1 0) converted to sRGB */
.test { background-color: color(xyz-d50 0 1 0); }
</style>
<body>
diff --git a/tests/wpt/tests/css/css-fonts/animations/font-palette-animation-not-specified-endpoints.html b/tests/wpt/tests/css/css-fonts/animations/font-palette-animation-not-specified-endpoints.html
new file mode 100644
index 00000000000..f3d103983c6
--- /dev/null
+++ b/tests/wpt/tests/css/css-fonts/animations/font-palette-animation-not-specified-endpoints.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<title>Font-palette animation with unspecified endpoints keyframes</title>
+<link rel="help" href="https://www.w3.org/TR/css-fonts-4/#propdef-font-palette">
+<meta name="assert" content="Font-palette should be animated if `from` and `to` keyframes are not specified.">
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+ @font-face {
+ font-family: "COLR-test-font";
+ src: url("../resources/COLR-palettes-test-font.ttf") format("truetype");
+ }
+ @font-palette-values --custom {
+ font-family: "COLR-test-font";
+ base-palette: 3;
+ }
+ @keyframes animFrom {
+ from {
+ font-palette: --custom;
+ }
+ }
+ @keyframes animTo {
+ to {
+ font-palette: --custom;
+ }
+ }
+ .demo {
+ font-family: "COLR-test-font";
+ font-size: 130px;
+ }
+ .animFrom {
+ animation: animFrom 0.1s forwards;
+ }
+ .animTo {
+ animation: animTo 0.1s forwards;
+ }
+</style>
+
+<body>
+ <div class="demo">
+ <div id="a" class="animTo">A</div>
+ <div id="b" class="animFrom">A</div>
+ </div>
+</body>
+
+<script>
+ var afterPaletteAnimationTest1 = async_test(
+ "Verify font-palette is animated when `from` keyframe is not specified"
+ );
+ document.getElementById("a").addEventListener("animationend",
+ afterPaletteAnimationTest1.step_func_done(function() {
+ assert_equals(window.getComputedStyle(
+ document.getElementById("a"))
+ .getPropertyValue('font-palette'), "--custom");
+ }));
+
+ var afterPaletteAnimationTest2 = async_test(
+ "Verify font-palette is animated when `to` keyframe is not specified"
+ );
+ document.getElementById("b").addEventListener("animationstart",
+ afterPaletteAnimationTest2.step_func_done(function() {
+ assert_not_equals(window.getComputedStyle(
+ document.getElementById("b"))
+ .getPropertyValue('font-palette'), "normal");
+ }));
+</script>
diff --git a/tests/wpt/tests/css/css-fonts/animations/font-palette-interpolation.html b/tests/wpt/tests/css/css-fonts/animations/font-palette-interpolation.html
index 66b0f00ebf0..43e1368412e 100644
--- a/tests/wpt/tests/css/css-fonts/animations/font-palette-interpolation.html
+++ b/tests/wpt/tests/css/css-fonts/animations/font-palette-interpolation.html
@@ -126,7 +126,7 @@ test(t => {
{ fontPalette: ['normal', 'dark'] },
{
duration: 1000,
- /* Should not affect anything, since <Color> type is not additive,
+ /* Should work like 'replace', since <Color> type is not additive,
compare: https://drafts.csswg.org/css-values-4/#combine-colors. */
composite: "add"
}
@@ -136,7 +136,7 @@ test(t => {
animation.currentTime = 500;
});
assert_equals(getComputedStyle(target).fontPalette,
- "palette-mix(in oklab, light, normal)");
+ "palette-mix(in oklab, normal, dark)");
}, "Test additive animations");
</script> \ No newline at end of file
diff --git a/tests/wpt/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-002.html b/tests/wpt/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-002.html
index 48ca92feef0..58b2db5ce4e 100644
--- a/tests/wpt/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-002.html
+++ b/tests/wpt/tests/css/css-highlight-api/painting/custom-highlight-font-metrics-002.html
@@ -5,7 +5,7 @@
<link rel="help" href="https://drafts.csswg.org/css-pseudo/#highlight-styling">
<link rel="match" href="custom-highlight-font-metrics-002-ref.html">
<meta name="assert" value="fonts relative units take the correct values, with correct cascade">
-<meta name="fuzzy" content="0-120;0-8">
+<meta name="fuzzy" content="0-128;0-8">
<head>
<style>
:root {
diff --git a/tests/wpt/tests/css/css-images/parsing/gradient-interpolation-method-computed.html b/tests/wpt/tests/css/css-images/parsing/gradient-interpolation-method-computed.html
index 9593a59777a..b4f8dee4393 100644
--- a/tests/wpt/tests/css/css-images/parsing/gradient-interpolation-method-computed.html
+++ b/tests/wpt/tests/css/css-images/parsing/gradient-interpolation-method-computed.html
@@ -23,13 +23,13 @@ const LINEAR_GRADIENT_SPECIFIERS = [
const RADIAL_GRADIENT_SPECIFIERS = [
{ input: '50px' },
- { input: 'ellipse 50% 40em', output: '50% 40em' },
- { input: 'at right center' },
+ { input: 'ellipse 50% 40em', output: '50% 640px' },
+ { input: 'at right center', output: 'at 100% 50%' },
];
const CONIC_GRADIENT_SPECIFIERS = [
{ input: 'from 30deg' },
- { input: 'at left 10px top 50em' },
+ { input: 'at left 10px top 50em', output: 'at 10px 800px' },
];
const legacy_stops = "red, blue"
diff --git a/tests/wpt/tests/css/css-lists/dynamic-counters-crash.html b/tests/wpt/tests/css/css-lists/dynamic-counters-crash.html
deleted file mode 100644
index 41e98ce0037..00000000000
--- a/tests/wpt/tests/css/css-lists/dynamic-counters-crash.html
+++ /dev/null
@@ -1,39 +0,0 @@
-<!DOCTYPE html>
-<html class="reftest-wait">
-<link rel="help" href="http://crbug.com/1492599">
-<style type="text/css">
-.c0:nth-last-child(odd) { counter-reset: counter; }
-.c1:nth-last-child(even) { counter-reset: counter; }
-.c1 + .c13 { counter-increment: counter -1; }
-.c10[class~="c10"] { counter-reset: counter; }
-</style>
-<script type="text/javascript">
-var nodes = Array();
-function boom() {
- nodes[16] = document.createElement('em');
- nodes[16].setAttribute('class', 'c0');
- document.documentElement.appendChild(nodes[16]);
- nodes[18] = document.createElement('colgroup');
- nodes[52] = document.createElement('table');
- document.documentElement.appendChild(nodes[52]);
- nodes[53] = document.createElement('abbr');
- nodes[53].setAttribute('class', 'c1');
- document.documentElement.appendChild(nodes[53]);
- nodes[54] = document.createElement('source');
- nodes[54].setAttribute('class', 'c10');
- nodes[55] = document.createElement('hgroup');
- nodes[55].setAttribute('class', 'c13');
- document.documentElement.appendChild(nodes[55]);
- nodes[66] = document.createElement('img');
- document.documentElement.appendChild(nodes[66]);
- nodes[71] = document.createElement('samp');
- document.documentElement.appendChild(nodes[71]);
- nodes[97] = document.createElement('del');
- document.documentElement.appendChild(nodes[97]);
- nodes[52].appendChild(nodes[54]);
- setTimeout('try { nodes[18].appendChild(nodes[71]); } catch(e) {}');
- document.documentElement.classList.remove("reftest-wait");
-}
-window.onload = boom;
-</script>
-</html>
diff --git a/tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-ellipse-mixed-change.html b/tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-ellipse-mixed-change.html
new file mode 100644
index 00000000000..e42d3ee08ed
--- /dev/null
+++ b/tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-ellipse-mixed-change.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<link rel="help" href="https://drafts.csswg.org/css-shapes-1/#basic-shape-interpolation">
+<link rel="match" href="clip-path-animation-ellipse-ref.html">
+<style>
+ .container {
+ width: 50px;
+ height: 50px;
+ background-color: green;
+ animation: clippath 20s steps(2, jump-end) -9.999s;
+ }
+
+ @keyframes clippath {
+ 0% {
+ clip-path: ellipse(60% 30% at 40px 80px);
+ }
+
+ 100% {
+ clip-path: ellipse(10% 20% at 10px 20px);
+ }
+ }
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="../../../../web-animations/resources/timing-utils.js"></script>
+
+<body>
+ <div id="target" class="container"></div>
+
+ <script>
+ document.getAnimations()[0].ready.then(() => {
+ document.getElementById('target').style.width = "100px";
+ document.getElementById('target').style.height = "100px";
+ waitForAnimationTime(document.getAnimations()[0], 1).then(takeScreenshot);
+ });
+ </script>
+</body>
+
+</html>
diff --git a/tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-ellipse-ref.html b/tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-ellipse-ref.html
new file mode 100644
index 00000000000..63b3174806f
--- /dev/null
+++ b/tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-ellipse-ref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<style>
+ .container {
+ width: 100px;
+ height: 100px;
+ background-color: green;
+ clip-path: ellipse(35% 25% at 25% 50%);
+ }
+</style>
+
+<body>
+ <div class="container"></div>
+</body>
+
+</html>
diff --git a/tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-ellipse.html b/tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-ellipse.html
new file mode 100644
index 00000000000..1c7c90ee844
--- /dev/null
+++ b/tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-ellipse.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<link rel="help" href="https://drafts.csswg.org/css-shapes-1/#basic-shape-interpolation">
+<link rel="match" href="clip-path-animation-ellipse-ref.html">
+<style>
+ .container {
+ width: 100px;
+ height: 100px;
+ background-color: green;
+ animation: clippath 20s steps(2, jump-end) -9.999s;
+ }
+
+ @keyframes clippath {
+ 0% {
+ clip-path: ellipse(60% 30% at 40% 80%);
+ }
+
+ 100% {
+ clip-path: ellipse(10% 20% at 10% 20%);
+ }
+ }
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="../../../../web-animations/resources/timing-utils.js"></script>
+
+<body>
+ <div class="container"></div>
+
+ <script>
+ waitForAnimationTime(document.getAnimations()[0], 1).then(takeScreenshot);
+ </script>
+</body>
+
+</html>
diff --git a/tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-font-size-inherited.html b/tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-font-size-inherited.html
new file mode 100644
index 00000000000..6836af5a295
--- /dev/null
+++ b/tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-font-size-inherited.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<link rel="help" href="https://drafts.csswg.org/css-shapes-1/#basic-shape-interpolation">
+<link rel="match" href="clip-path-animation-font-size-ref.html">
+<style>
+ body {
+ font-size: 20px;
+ }
+
+ .container {
+ width: 100px;
+ height: 100px;
+ background-color: green;
+ animation: clippath 20s steps(2, jump-end) -9.999s;
+ }
+
+ @keyframes clippath {
+ 0% {
+ clip-path: circle(1em);
+ }
+
+ 100% {
+ clip-path: circle(2em);
+ }
+ }
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="../../../../web-animations/resources/timing-utils.js"></script>
+
+<body>
+ <div class="container"></div>
+
+ <script>
+ waitForAnimationTime(document.getAnimations()[0], 1).then(takeScreenshot);
+ </script>
+</body>
+
+</html>
diff --git a/tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-font-size-mixed-change.html b/tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-font-size-mixed-change.html
new file mode 100644
index 00000000000..9e24aa905c2
--- /dev/null
+++ b/tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-font-size-mixed-change.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<link rel="help" href="https://drafts.csswg.org/css-shapes-1/#basic-shape-interpolation">
+<link rel="match" href="clip-path-animation-font-size-ref.html">
+<style>
+ .container {
+ width: 100px;
+ height: 100px;
+ font-size: 10px;
+ background-color: green;
+ /* Use a long animation that start at 50% progress where the slope of the
+ selected timing function is zero. By setting up the animation in this way,
+ we accommodate lengthy delays in running the test without a potential drift
+ in the animated property value. This is important for avoiding flakes,
+ especially on debug builds. The screenshots are taken as soon as the
+ animation is ready, thus the long animation duration has no bearing on
+ the actual duration of the test. */
+ animation: clippath 20s steps(2, jump-end) -9.999999s;
+ }
+
+ @keyframes clippath {
+ 0% {
+ clip-path: circle(20px);
+ }
+
+ 100% {
+ clip-path: circle(2em);
+ }
+ }
+</style>
+<script src="/common/reftest-wait.js"></script>
+
+<body>
+ <div id="target" class="container"></div>
+
+ <script>
+ document.getAnimations()[0].ready.then(() => {
+ document.getElementById('target').style.fontSize = "20px";
+ window.requestAnimationFrame(() => {
+ takeScreenshot();
+ })
+ });
+ </script>
+</body>
+
+</html>
diff --git a/tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-font-size-ref.html b/tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-font-size-ref.html
new file mode 100644
index 00000000000..912a8e84642
--- /dev/null
+++ b/tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-font-size-ref.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<style>
+ .container {
+ width: 100px;
+ height: 100px;
+ background-color: green;
+ font-size: 20px;
+ clip-path: circle(1.5em);
+ }
+</style>
+
+<body>
+ <div class="container"></div>
+</body>
+
+</html>
diff --git a/tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-font-size.html b/tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-font-size.html
new file mode 100644
index 00000000000..00563305e54
--- /dev/null
+++ b/tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-font-size.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<link rel="help" href="https://drafts.csswg.org/css-shapes-1/#basic-shape-interpolation">
+<link rel="match" href="clip-path-animation-font-size-ref.html">
+<style>
+ .container {
+ width: 100px;
+ height: 100px;
+ font-size: 20px;
+ background-color: green;
+ animation: clippath 20s steps(2, jump-end) -9.999s;
+ }
+
+ @keyframes clippath {
+ 0% {
+ clip-path: circle(1em);
+ }
+
+ 100% {
+ clip-path: circle(2em);
+ }
+ }
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="../../../../web-animations/resources/timing-utils.js"></script>
+
+<body>
+ <div class="container"></div>
+
+ <script>
+ waitForAnimationTime(document.getAnimations()[0], 1).then(takeScreenshot);
+ </script>
+</body>
+
+</html>
diff --git a/tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-path-ref.html b/tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-path-ref.html
new file mode 100644
index 00000000000..d53067f5634
--- /dev/null
+++ b/tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-path-ref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<style>
+ .container {
+ width: 200px;
+ height: 200px;
+ background-color: green;
+ clip-path: path('M 0 150 L 15,75 A 5,5 0,0,1 150,75 L 150 150 z');
+ }
+</style>
+
+<body>
+ <div class="container"></div>
+</body>
+
+</html>
diff --git a/tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-path.html b/tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-path.html
new file mode 100644
index 00000000000..20400ba5ece
--- /dev/null
+++ b/tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-path.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<link rel="help" href="https://drafts.csswg.org/css-shapes-1/#basic-shape-interpolation">
+<link rel="match" href="clip-path-animation-path-ref.html">
+<meta name=fuzzy content="0-10;0-200">
+<style>
+ .container {
+ width: 200px;
+ height: 200px;
+ background-color: green;
+ animation: clippath 20s steps(2, jump-end) -9.999s;
+ }
+
+ @keyframes clippath {
+ 0% {
+ clip-path: path('M 0 200 L 0,75 A 5,5 0,0,1 150,75 L 150 200 z');
+ }
+
+ 100% {
+ clip-path: path('M 0 100 L 30,75 A 5,5 0,0,1 150,75 L 150 100 z');
+ }
+ }
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="../../../../web-animations/resources/timing-utils.js"></script>
+
+<body>
+ <div class="container"></div>
+
+ <script>
+ waitForAnimationTime(document.getAnimations()[0], 1).then(takeScreenshot);
+ </script>
+</body>
+
+</html>
diff --git a/tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-polygon-mixed-change.html b/tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-polygon-mixed-change.html
new file mode 100644
index 00000000000..569c0af66ae
--- /dev/null
+++ b/tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-polygon-mixed-change.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<link rel="help" href="https://drafts.csswg.org/css-shapes-1/#basic-shape-interpolation">
+<link rel="match" href="clip-path-animation-polygon-ref.html">
+<style>
+ .container {
+ width: 50px;
+ height: 50px;
+ background-color: green;
+ animation: clippath 20s steps(2, jump-end) -9.999s;
+ }
+
+ @keyframes clippath {
+ 0% {
+ clip-path: polygon(0px 0px, 100% 0%, 50% 100%)
+ }
+
+ 100% {
+ clip-path: polygon(20px 20px, 80% 20%, 50% 80%)
+ }
+ }
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="../../../../web-animations/resources/timing-utils.js"></script>
+
+<body>
+ <div id="target" class="container"></div>
+
+ <script>
+ document.getAnimations()[0].ready.then(() => {
+ document.getElementById('target').style.width = "100px";
+ document.getElementById('target').style.height = "100px";
+ waitForAnimationTime(document.getAnimations()[0], 1).then(takeScreenshot);
+ });
+ </script>
+</body>
+
+</html>
diff --git a/tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-polygon-ref.html b/tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-polygon-ref.html
new file mode 100644
index 00000000000..28e11e966d5
--- /dev/null
+++ b/tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-polygon-ref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<style>
+ .container {
+ width: 100px;
+ height: 100px;
+ background-color: green;
+ clip-path: polygon(10% 10%, 90% 10%, 50% 90%);
+ }
+</style>
+
+<body>
+ <div class="container"></div>
+</body>
+
+</html>
diff --git a/tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-polygon.html b/tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-polygon.html
new file mode 100644
index 00000000000..1a9d0cc1688
--- /dev/null
+++ b/tests/wpt/tests/css/css-masking/clip-path/animations/clip-path-animation-polygon.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<link rel="help" href="https://drafts.csswg.org/css-shapes-1/#basic-shape-interpolation">
+<link rel="match" href="clip-path-animation-polygon-ref.html">
+<style>
+ .container {
+ width: 100px;
+ height: 100px;
+ background-color: green;
+ animation: clippath 20s steps(2, jump-end) -9.999s;
+ }
+
+ @keyframes clippath {
+ 0% {
+ clip-path: polygon(0% 0%, 100% 0%, 50% 100%)
+ }
+
+ 100% {
+ clip-path: polygon(20% 20%, 80% 20%, 50% 80%)
+ }
+ }
+</style>
+<script src="/common/reftest-wait.js"></script>
+<script src="../../../../web-animations/resources/timing-utils.js"></script>
+
+<body>
+ <div class="container"></div>
+
+ <script>
+ waitForAnimationTime(document.getAnimations()[0], 1).then(takeScreenshot);
+ </script>
+</body>
+
+</html>
diff --git a/tests/wpt/tests/css/css-masking/mask-image/mask-image-3b.html b/tests/wpt/tests/css/css-masking/mask-image/mask-image-3b.html
index bd805cde975..b6609fde6a4 100644
--- a/tests/wpt/tests/css/css-masking/mask-image/mask-image-3b.html
+++ b/tests/wpt/tests/css/css-masking/mask-image/mask-image-3b.html
@@ -8,6 +8,7 @@
<link rel="help" href="https://www.w3.org/TR/css-masking-1/#the-mask-image">
<link rel="match" href="mask-image-3-ref.html">
<meta name="assert" content="Test checks whether SVG mask and image as mask layer works correctly or not.">
+ <meta name="fuzzy" content="0-1; 0-100">
<svg height="0">
<mask id="mask1" x="0" y="0" width="1" height="1" >
<circle cx="50" cy="50" r="25" style="stroke:none; fill: #ffffff"/>
diff --git a/tests/wpt/tests/css/css-masking/mask-image/mask-image-3c.html b/tests/wpt/tests/css/css-masking/mask-image/mask-image-3c.html
index 32bd4454d71..91cc9f7bb10 100644
--- a/tests/wpt/tests/css/css-masking/mask-image/mask-image-3c.html
+++ b/tests/wpt/tests/css/css-masking/mask-image/mask-image-3c.html
@@ -8,6 +8,7 @@
<link rel="help" href="https://www.w3.org/TR/css-masking-1/#the-mask-image">
<link rel="match" href="mask-image-3-ref.html">
<meta name="assert" content="Test checks whether SVG mask and image as mask layer works correctly or not.">
+ <meta name="fuzzy" content="0-1; 0-100">
<svg height="0">
<mask id="mask1" x="0" y="0" width="1" height="1" >
<circle cx="50" cy="50" r="25" style="stroke:none; fill: #ffffff"/>
diff --git a/tests/wpt/tests/css/css-masking/mask-image/mask-image-3d.html b/tests/wpt/tests/css/css-masking/mask-image/mask-image-3d.html
index f1ef1be7099..468872fecbd 100644
--- a/tests/wpt/tests/css/css-masking/mask-image/mask-image-3d.html
+++ b/tests/wpt/tests/css/css-masking/mask-image/mask-image-3d.html
@@ -7,6 +7,7 @@
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
<link rel="help" href="https://www.w3.org/TR/css-masking-1/#the-mask-image">
<link rel="match" href="mask-image-3-ref.html">
+ <meta name="fuzzy" content="0-1; 0-100">
<meta name="assert" content="Test checks whether SVG mask and image as mask layer works correctly or not.">
<svg height="0">
<mask id="mask1" x="10%" y="10%" width="0.8" height="0.8" >
diff --git a/tests/wpt/tests/css/css-masking/mask-image/mask-image-3e.html b/tests/wpt/tests/css/css-masking/mask-image/mask-image-3e.html
index 15223e34d62..5e539375545 100644
--- a/tests/wpt/tests/css/css-masking/mask-image/mask-image-3e.html
+++ b/tests/wpt/tests/css/css-masking/mask-image/mask-image-3e.html
@@ -8,6 +8,7 @@
<link rel="help" href="https://www.w3.org/TR/css-masking-1/#the-mask-image">
<link rel="match" href="mask-image-3-ref.html">
<meta name="assert" content="Test checks whether SVG mask and image as mask layer works correctly or not.">
+ <meta name="fuzzy" content="0-1; 0-100">
<svg height="0">
<mask id="mask1" x="0" y="0" width="1" height="1" >
<circle cx="50" cy="50" r="25" style="stroke:none; fill: #ffffff"/>
diff --git a/tests/wpt/tests/css/css-masking/mask-image/mask-image-3f.html b/tests/wpt/tests/css/css-masking/mask-image/mask-image-3f.html
index e925105baac..0ecfd383652 100644
--- a/tests/wpt/tests/css/css-masking/mask-image/mask-image-3f.html
+++ b/tests/wpt/tests/css/css-masking/mask-image/mask-image-3f.html
@@ -8,6 +8,7 @@
<link rel="help" href="https://www.w3.org/TR/css-masking-1/#the-mask-image">
<link rel="match" href="mask-image-3-ref.html">
<meta name="assert" content="Test checks whether SVG mask layer can be positioned on box-shadow area correctly or not.">
+ <meta name="fuzzy" content="0-1; 0-100">
<svg height="0">
<mask id="mask1" x="-100" y="-100" width="300" height="300" maskUnits="userSpaceOnUse">
<rect x="-100" y="-100" width="50" height="50" style="stroke:none; fill: #ffffff"/>
diff --git a/tests/wpt/tests/css/css-masking/mask-image/mask-image-3g.html b/tests/wpt/tests/css/css-masking/mask-image/mask-image-3g.html
index 1236c0c3348..133a69fa609 100644
--- a/tests/wpt/tests/css/css-masking/mask-image/mask-image-3g.html
+++ b/tests/wpt/tests/css/css-masking/mask-image/mask-image-3g.html
@@ -8,6 +8,7 @@
<link rel="help" href="https://www.w3.org/TR/css-masking-1/#the-mask-image">
<link rel="match" href="mask-image-3-ref.html">
<meta name="assert" content="Test checks whether apply transfrom to a SVG mask layer works correctly or not.">
+ <meta name="fuzzy" content="0-1; 0-100">
<svg height="0">
<mask id="mask1" x="-100" y="-100" width="300" height="300" maskUnits="userSpaceOnUse">
<rect x="-100" y="-100" width="50" height="50" style="stroke:none; fill: #ffffff"/>
diff --git a/tests/wpt/tests/css/css-masking/parsing/mask-computed.html b/tests/wpt/tests/css/css-masking/parsing/mask-computed.html
new file mode 100644
index 00000000000..28fc38defae
--- /dev/null
+++ b/tests/wpt/tests/css/css-masking/parsing/mask-computed.html
@@ -0,0 +1,94 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Masking Module Level 1: getComputedStyle().mask</title>
+<link rel="help" href="https://www.w3.org/TR/css-masking-1/#the-mask">
+<meta name="assert" content="mask computed value is as specified.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/computed-testcommon.js"></script>
+</head>
+<body>
+<div id="target"></div>
+<script>
+// value: <mask-layer>#
+// <mask-layer> =
+// <mask-reference> ||
+// <position> [ / <bg-size> ]? ||
+// <repeat-style> ||
+// <geometry-box> ||
+// [ <geometry-box> | no-clip ] ||
+// <compositing-operator> ||
+// <masking-mode>
+
+// <mask-reference> = none | <image> | <mask-source>
+test_computed_value('mask', 'none');
+test_computed_value('mask',
+ 'linear-gradient(to left bottom, red, blue)',
+ 'linear-gradient(to left bottom, rgb(255, 0, 0), rgb(0, 0, 255))');
+test_computed_value('mask',
+ 'linear-gradient(to left bottom, red, blue) luminance',
+ 'linear-gradient(to left bottom, rgb(255, 0, 0), rgb(0, 0, 255)) luminance');
+test_computed_value('mask', 'url("https://example.com/")');
+
+// <position> [ / <bg-size> ]?
+test_computed_value('mask',
+ 'linear-gradient(to left bottom, red, blue) 1px 2px',
+ 'linear-gradient(to left bottom, rgb(255, 0, 0), rgb(0, 0, 255)) 1px 2px');
+test_computed_value('mask', 'url("https://example.com/") 1px 2px / contain');
+
+// <repeat-style> = repeat-x | repeat-y | [repeat | space | round | no-repeat]{1,2}
+test_computed_value('mask', 'repeat-y');
+
+// <geometry-box> = <shape-box> | fill-box | stroke-box | view-box
+// <shape-box> = <box>
+// <box> = border-box | padding-box | content-box
+test_computed_value('mask', 'border-box', 'none');
+test_computed_value('mask',
+ 'linear-gradient(to left bottom, red, blue) padding-box',
+ 'linear-gradient(to left bottom, rgb(255, 0, 0), rgb(0, 0, 255)) padding-box');
+test_computed_value('mask', 'content-box');
+test_computed_value('mask', 'url("https://example.com/") fill-box');
+test_computed_value('mask',
+ 'linear-gradient(to left bottom, red, blue) stroke-box',
+ 'linear-gradient(to left bottom, rgb(255, 0, 0), rgb(0, 0, 255)) stroke-box');
+test_computed_value('mask', 'view-box');
+
+// [ <geometry-box> | no-clip ]
+test_computed_value('mask', 'no-clip');
+
+// <compositing-operator> = add | subtract | intersect | exclude
+test_computed_value('mask',
+ 'url("https://example.com/") add',
+ 'url("https://example.com/")');
+test_computed_value('mask', 'subtract');
+test_computed_value('mask', 'url("https://example.com/") intersect');
+test_computed_value('mask',
+ 'linear-gradient(to left bottom, red, blue) exclude',
+ 'linear-gradient(to left bottom, rgb(255, 0, 0), rgb(0, 0, 255)) exclude');
+
+// <masking-mode> = alpha | luminance | auto
+test_computed_value('mask', 'alpha');
+test_computed_value('mask', 'url("https://example.com/") alpha');
+
+// Test the combination of mask-origin and mask-clip.
+test_computed_value('mask', 'border-box border-box', 'none');
+test_computed_value('mask', 'content-box content-box', 'content-box');
+test_computed_value('mask', 'border-box content-box', 'border-box content-box');
+test_computed_value('mask', 'border-box no-clip', 'no-clip');
+
+// <mask-layer> = <mask-reference> || <position> [ / <bg-size> ]? || <repeat-style> ||
+// <geometry-box> || [ <geometry-box> | no-clip ] || <compositing-operator> || <masking-mode>
+test_computed_value('mask',
+ 'intersect no-clip space round 1px 2px / contain stroke-box linear-gradient(to left bottom, red, blue) luminance',
+ 'linear-gradient(to left bottom, rgb(255, 0, 0), rgb(0, 0, 255)) 1px 2px / contain space round stroke-box no-clip intersect luminance');
+test_computed_value('mask',
+ 'intersect no-clip space round 1px 2px / contain view-box, stroke-box linear-gradient(to left bottom, red, blue) luminance',
+ '1px 2px / contain space round view-box no-clip intersect, linear-gradient(to left bottom, rgb(255, 0, 0), rgb(0, 0, 255)) stroke-box luminance');
+
+test_computed_value('mask', 'none alpha', 'alpha');
+
+</script>
+</body>
+</html>
diff --git a/tests/wpt/tests/css/css-masking/parsing/mask-valid.sub.html b/tests/wpt/tests/css/css-masking/parsing/mask-valid.sub.html
index a377060ded8..c4d2d4eb2c0 100644
--- a/tests/wpt/tests/css/css-masking/parsing/mask-valid.sub.html
+++ b/tests/wpt/tests/css/css-masking/parsing/mask-valid.sub.html
@@ -51,6 +51,12 @@ test_valid_value('mask', 'linear-gradient(to left bottom, red, blue) exclude');
test_valid_value('mask', 'alpha');
test_valid_value('mask', 'url("https://{{host}}/") alpha');
+// Test the combination of mask-origin and mask-clip.
+test_valid_value('mask', 'border-box border-box', 'none');
+test_valid_value('mask', 'content-box content-box', 'content-box');
+test_valid_value('mask', 'border-box content-box', 'border-box content-box');
+test_valid_value('mask', 'border-box no-clip', 'no-clip');
+
// <mask-layer> = <mask-reference> || <position> [ / <bg-size> ]? || <repeat-style> ||
// <geometry-box> || [ <geometry-box> | no-clip ] || <compositing-operator> || <masking-mode>
test_valid_value('mask',
diff --git a/tests/wpt/tests/css/css-properties-values-api/animation/custom-property-animation-transform-list-multiple-values.html b/tests/wpt/tests/css/css-properties-values-api/animation/custom-property-animation-transform-list-multiple-values.html
index 9ffaec830f8..1b2fc907f25 100644
--- a/tests/wpt/tests/css/css-properties-values-api/animation/custom-property-animation-transform-list-multiple-values.html
+++ b/tests/wpt/tests/css/css-properties-values-api/animation/custom-property-animation-transform-list-multiple-values.html
@@ -3,6 +3,7 @@
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../resources/utils.js"></script>
+<script src="/web-animations/testcommon.js"></script>
<div id="target"></div>
<script>
@@ -60,7 +61,8 @@ animation_test({
initialValue: "translateX(0px)"
}, {
keyframes: ["translateX(100px) scale(2)", "rotate(180deg)"],
- expected: "matrix(0, -1.5, 1.5, 0, 50, 0)"
+ expected: "matrix(0, -1.5, 1.5, 0, 50, 0)",
+ assert_function: assert_matrix_equals
}, 'Animating a custom property of type <transform-list> containing multiple values and with mismatching list lengths');
</script>
diff --git a/tests/wpt/tests/css/css-properties-values-api/animation/custom-property-animation-transform-none.tentative.html b/tests/wpt/tests/css/css-properties-values-api/animation/custom-property-animation-transform-none.tentative.html
new file mode 100644
index 00000000000..37abddd2271
--- /dev/null
+++ b/tests/wpt/tests/css/css-properties-values-api/animation/custom-property-animation-transform-none.tentative.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api-1">
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/9522">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../resources/utils.js"></script>
+<div id="target"></div>
+<script>
+
+// Move to custom-property-animation-transform-list-single-values.html when no longer tentative
+animation_test({
+ syntax: "<transform-list>|none",
+ inherits: false,
+ initialValue: "none"
+}, {
+ keyframes: ["translateX(200px)"],
+ expected: "translateX(200px)"
+}, 'Animating a custom property of type "<transform-list>|none" from "none" to <transform-list> value');
+
+// Move to custom-property-animation-transform-function.html when no longer tentative
+animation_test({
+ syntax: "<transform-function>|none",
+ inherits: false,
+ initialValue: "none"
+}, {
+ keyframes: ["translateX(200px)"],
+ expected: "translateX(200px)"
+}, 'Animating a custom property of type "<transform-function>|none" from "none" to <transform-function> value');
+
+</script>
diff --git a/tests/wpt/tests/css/css-properties-values-api/animation/custom-property-transition-transform-function-box-size.tentative.html b/tests/wpt/tests/css/css-properties-values-api/animation/custom-property-transition-transform-function-box-size.tentative.html
new file mode 100644
index 00000000000..23ac09b1fc9
--- /dev/null
+++ b/tests/wpt/tests/css/css-properties-values-api/animation/custom-property-transition-transform-function-box-size.tentative.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api-1">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#interpolate">
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/2854">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../resources/utils.js"></script>
+<div id="target"></div>
+<script>
+
+transition_test({
+ syntax: "<transform-function>",
+ from: "translateX(50%)",
+ to: "scale(4)",
+ expected: "mix(50%; translateX(50%); scale(4))",
+ behavior: 'allow-discrete',
+}, 'A custom property of type <transform-function> yields a CSS Transition using the mix function for a box size dependent matrix interpolation');
+
+</script>
diff --git a/tests/wpt/tests/css/css-properties-values-api/animation/custom-property-transition-transform-function-matrix.html b/tests/wpt/tests/css/css-properties-values-api/animation/custom-property-transition-transform-function-matrix.html
new file mode 100644
index 00000000000..00b50181425
--- /dev/null
+++ b/tests/wpt/tests/css/css-properties-values-api/animation/custom-property-transition-transform-function-matrix.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api-1">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../resources/utils.js"></script>
+<div id="target"></div>
+<script>
+
+transition_test({
+ syntax: "<transform-function>",
+ from: "translateZ(100px)",
+ to: "scale(4)",
+ expected: "matrix3d(2.5, 0, 0, 0, 0, 2.5, 0, 0, 0, 0, 1, 0, 0, 0, 50, 1)",
+ behavior: 'allow-discrete',
+}, 'A custom property of type <transform-function> can yield a CSS Transition between different function types');
+
+</script>
diff --git a/tests/wpt/tests/css/css-properties-values-api/animation/custom-property-transition-transform-function-none.tentative.html b/tests/wpt/tests/css/css-properties-values-api/animation/custom-property-transition-transform-function-none.tentative.html
new file mode 100644
index 00000000000..29a5715fec8
--- /dev/null
+++ b/tests/wpt/tests/css/css-properties-values-api/animation/custom-property-transition-transform-function-none.tentative.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api-1">
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/9522">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../resources/utils.js"></script>
+<div id="target"></div>
+<script>
+
+transition_test({
+ syntax: "<transform-function>|none",
+ from: "none",
+ to: "translateX(200px)",
+ expected: "translateX(200px)",
+ behavior: 'allow-discrete',
+}, 'A custom property keyword none is not a <transform-function> value and is not interpolable with <transform-function> values');
+
+</script>
diff --git a/tests/wpt/tests/css/css-properties-values-api/animation/custom-property-transition-transform-function-to-list.html b/tests/wpt/tests/css/css-properties-values-api/animation/custom-property-transition-transform-function-to-list.html
new file mode 100644
index 00000000000..d09fb6416ac
--- /dev/null
+++ b/tests/wpt/tests/css/css-properties-values-api/animation/custom-property-transition-transform-function-to-list.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api-1">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../resources/utils.js"></script>
+<div id="target"></div>
+<script>
+
+transition_test({
+ syntax: "<transform-function>|<transform-list>",
+ from: "translateX(100px)",
+ to: "translateX(200px) rotate(90deg)",
+ expected: "translateX(200px) rotate(90deg)",
+ behavior: 'allow-discrete',
+}, 'A custom property cannot yield a CSS Transition from <transform-function> to <transform-list>');
+
+</script>
diff --git a/tests/wpt/tests/css/css-properties-values-api/animation/custom-property-transition-transform-list-box-size.tentative.html b/tests/wpt/tests/css/css-properties-values-api/animation/custom-property-transition-transform-list-box-size.tentative.html
new file mode 100644
index 00000000000..d1b882f7084
--- /dev/null
+++ b/tests/wpt/tests/css/css-properties-values-api/animation/custom-property-transition-transform-list-box-size.tentative.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api-1">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#interpolate">
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/2854">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../resources/utils.js"></script>
+<div id="target"></div>
+<script>
+
+transition_test({
+ syntax: "<transform-list>",
+ from: "translateX(50%)",
+ to: "scale(4)",
+ expected: "mix(50%; translateX(50%); scale(4))",
+ behavior: 'allow-discrete',
+}, 'A custom property of type <transform-list> yields a CSS Transition using the mix function for a box size dependent matrix interpolation');
+
+</script>
diff --git a/tests/wpt/tests/css/css-properties-values-api/animation/custom-property-transition-transform-list-matrix.html b/tests/wpt/tests/css/css-properties-values-api/animation/custom-property-transition-transform-list-matrix.html
new file mode 100644
index 00000000000..8f1fa842948
--- /dev/null
+++ b/tests/wpt/tests/css/css-properties-values-api/animation/custom-property-transition-transform-list-matrix.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api-1">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../resources/utils.js"></script>
+<div id="target"></div>
+<script>
+
+transition_test({
+ syntax: "<transform-list>",
+ from: "translateZ(100px)",
+ to: "scale(4)",
+ expected: "matrix3d(2.5, 0, 0, 0, 0, 2.5, 0, 0, 0, 0, 1, 0, 0, 0, 50, 1)",
+ behavior: 'allow-discrete',
+}, 'A custom property of type <transform-list> can yield a CSS Transition between different function types');
+
+</script>
diff --git a/tests/wpt/tests/css/css-properties-values-api/animation/custom-property-transition-transform-list-none.tentative.html b/tests/wpt/tests/css/css-properties-values-api/animation/custom-property-transition-transform-list-none.tentative.html
new file mode 100644
index 00000000000..d09f5854b30
--- /dev/null
+++ b/tests/wpt/tests/css/css-properties-values-api/animation/custom-property-transition-transform-list-none.tentative.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api-1">
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/9522">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../resources/utils.js"></script>
+<div id="target"></div>
+<script>
+
+transition_test({
+ syntax: "<transform-list>|none",
+ from: "none",
+ to: "translateX(200px)",
+ expected: "translateX(200px)",
+ behavior: 'allow-discrete',
+}, 'A custom property keyword none is not a <transform-list> value and is not interpolable with <transform-list> values');
+
+</script>
diff --git a/tests/wpt/tests/css/css-properties-values-api/resources/utils.js b/tests/wpt/tests/css/css-properties-values-api/resources/utils.js
index fc3a5993cf5..a952a4feedc 100644
--- a/tests/wpt/tests/css/css-properties-values-api/resources/utils.js
+++ b/tests/wpt/tests/css/css-properties-values-api/resources/utils.js
@@ -144,7 +144,8 @@ function animation_test(property, values, description) {
// iterationComposite is set to something other than "replace".
animation.currentTime = duration * 2.5;
- assert_equals(getComputedStyle(target).getPropertyValue(name), values.expected);
+ const assert_equals_function = values.assert_function || assert_equals;
+ assert_equals_function(getComputedStyle(target).getPropertyValue(name), values.expected);
}, description);
};
diff --git a/tests/wpt/tests/css/css-scoping/chrome-1492368-crash.html b/tests/wpt/tests/css/css-scoping/chrome-1492368-crash.html
new file mode 100644
index 00000000000..04d48ef2153
--- /dev/null
+++ b/tests/wpt/tests/css/css-scoping/chrome-1492368-crash.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<title>Chrome crash re-assigning to slots with display:none slot</title>
+<link rel="help" href="https://crbug.com/1492368">
+<div id="host">
+ <span id="slotted" style="display:none"></span>
+</div>
+<script>
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `
+ <slot></slot>
+ <slot name="s1" style="display:none"></slot>
+ `;
+ host.offsetTop;
+ slotted.setAttribute("slot", "s1");
+ slotted.style.color = "green";
+ host.offsetTop;
+</script>
diff --git a/tests/wpt/tests/css/css-scroll-anchoring/after-scrollable-range-shrinkage-003.html b/tests/wpt/tests/css/css-scroll-anchoring/after-scrollable-range-shrinkage-003.html
new file mode 100644
index 00000000000..c9127e79b5a
--- /dev/null
+++ b/tests/wpt/tests/css/css-scroll-anchoring/after-scrollable-range-shrinkage-003.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+<meta name="viewport" content="width=device-width">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="author" title="Mozilla" href="https://mozilla.org">
+<link rel="help" href="https://drafts.csswg.org/css-scroll-anchoring/">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1856088">
+<div style="height: 500vh;"></div>
+<div id="anchor" style="height: 10px; background-color: blue;"></div>
+<div style="height: 200vh;"></div>
+<script>
+promise_test(async t => {
+ assert_equals(window.scrollY, 0);
+
+ let anchorRect = anchor.getBoundingClientRect();
+ // Scroll to the anchor node.
+ window.scrollBy(0, anchorRect.y);
+ assert_equals(window.scrollY, anchorRect.y);
+
+ await new Promise(resolve => t.step_timeout(resolve, 0));
+
+ // Shrink the first element so that scroll anchoring happens.
+ document.querySelectorAll("div")[0].style.height = "200vh";
+ // Flush the change.
+ document.querySelectorAll("div")[0].getBoundingClientRect();
+
+ await new Promise(resolve => window.addEventListener("scroll", resolve));
+
+ // Revert the height change in a scroll event handler.
+ document.querySelectorAll("div")[0].style.height = "500vh";
+
+ await new Promise(resolve => requestAnimationFrame(resolve));
+ await new Promise(resolve => requestAnimationFrame(resolve));
+
+ assert_equals(window.scrollY, anchorRect.y);
+}, "Scroll anchoring properly works after scrollable range shrinkage");
+</script>
+</html>
diff --git a/tests/wpt/tests/css/css-scroll-anchoring/after-scrollable-range-shrinkage-004.html b/tests/wpt/tests/css/css-scroll-anchoring/after-scrollable-range-shrinkage-004.html
new file mode 100644
index 00000000000..8509a1cca5e
--- /dev/null
+++ b/tests/wpt/tests/css/css-scroll-anchoring/after-scrollable-range-shrinkage-004.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+<meta name="viewport" content="width=device-width">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="author" title="Mozilla" href="https://mozilla.org">
+<link rel="help" href="https://drafts.csswg.org/css-scroll-anchoring/">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1856088">
+<div style="height: 500vh;"></div>
+<div id="anchor" style="height: 10px; background-color: blue;"></div>
+<div style="height: 200vh;"></div>
+<script>
+promise_test(async t => {
+ assert_equals(window.scrollY, 0);
+
+ let anchorRect = anchor.getBoundingClientRect();
+ // Scroll to the anchor node.
+ window.scrollBy(0, anchorRect.y);
+ assert_equals(window.scrollY, anchorRect.y);
+
+ await new Promise(resolve => t.step_timeout(resolve, 0));
+
+ // Shrink the first element so that scroll anchoring happens.
+ document.querySelectorAll("div")[0].style.height = "200vh";
+ // Flush the change.
+ document.querySelectorAll("div")[0].getBoundingClientRect();
+
+ await new Promise(resolve => window.addEventListener("scroll", resolve));
+
+ // Shrink the first element more.
+ document.querySelectorAll("div")[0].style.height = "100vh";
+
+ await new Promise(resolve => requestAnimationFrame(resolve));
+ await new Promise(resolve => requestAnimationFrame(resolve));
+
+ const scrollAnchorPosition = window.scrollY;
+
+ // Scroll back to (0, 0) to calculate the expected scroll anchor element
+ // position.
+ window.scrollTo(0, 0);
+ anchorRect = anchor.getBoundingClientRect();
+ assert_equals(scrollAnchorPosition, anchorRect.y);
+}, "Scroll anchoring properly works after scrollable range shrinkage");
+</script>
+</html>
diff --git a/tests/wpt/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-aligns-with-snap-align.tentative.html b/tests/wpt/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-aligns-with-snap-align.tentative.html
new file mode 100644
index 00000000000..6b133dea7d7
--- /dev/null
+++ b/tests/wpt/tests/css/css-scroll-snap-2/scroll-start-target/scroll-start-target-aligns-with-snap-align.tentative.html
@@ -0,0 +1,74 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title> CSS Scroll Snap 2 Test: scroll-start-target*</title>
+ <link rel="help" href="https://drafts.csswg.org/css-scroll-snap-2/#scroll-start-target">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/dom/events/scrolling/scroll_support.js"></script>
+ </head>
+ <body>
+ <style>
+ #space {
+ width: 1000px;
+ height: 1000px;
+ border: solid 1px red;
+ }
+ #scroller {
+ width: 400px;
+ height: 400px;
+ overflow: hidden;
+ border: solid 1px blue;
+ position: absolute;
+ }
+ #target {
+ width: 100px;
+ height: 100px;
+ background-color: pink;
+ scroll-start-target: auto auto;
+ position: absolute;
+ top: 400px;
+ left: 400px;
+ }
+ </style>
+ <div id="scroller">
+ <div id="space"></div>
+ <div id="target"></div>
+ </div>
+ <script>
+ promise_test(async (t) => {
+ await waitForCompositorCommit();
+
+ assert_equals(scroller.scrollTop, 400,
+ "scroller is vertically scrolled to target");
+ assert_equals(scroller.scrollLeft, 400,
+ "scroller is horizontally scrolled to target");
+
+ target.style.scrollSnapAlign = "center";
+ await waitForCompositorCommit();
+
+ assert_equals(scroller.scrollTop, 250,
+ "scroller is vertically aligned to target's center");
+ assert_equals(scroller.scrollLeft, 250,
+ "scroller is horizontally aligned to target's center");
+
+ target.style.scrollSnapAlign = "end";
+ await waitForCompositorCommit();
+
+ assert_equals(scroller.scrollTop, 100,
+ "scroller is vertically aligned to target's bottom");
+ assert_equals(scroller.scrollLeft, 100,
+ "scroller is horizontally aligned to target's right");
+
+ target.style.scrollSnapAlign = "start";
+ await waitForCompositorCommit();
+
+ assert_equals(scroller.scrollTop, 400,
+ "scroller is vertically aligned to target's top");
+ assert_equals(scroller.scrollLeft, 400,
+ "scroller is horizontally aligned to target's left");
+ }, "scroll-start-target aligns with scroll-snap-align");
+ </script>
+ </body>
+</html>
diff --git a/tests/wpt/tests/css/css-text/crashtests/text-indent-each-line-crash.html b/tests/wpt/tests/css/css-text/crashtests/text-indent-each-line-crash.html
new file mode 100644
index 00000000000..fb63175cf17
--- /dev/null
+++ b/tests/wpt/tests/css/css-text/crashtests/text-indent-each-line-crash.html
@@ -0,0 +1,14 @@
+<style>
+*:scope {
+ text-indent: 41% each-line;
+ columns: 0;
+}
+#a {
+ float: right;
+ writing-mode: tb;
+}
+</style>
+<shadow id="a">
+A
+</shadow>
+<details> \ No newline at end of file
diff --git a/tests/wpt/tests/css/css-text/inheritance.html b/tests/wpt/tests/css/css-text/inheritance.html
index 83d1d4971ea..2043afe999d 100644
--- a/tests/wpt/tests/css/css-text/inheritance.html
+++ b/tests/wpt/tests/css/css-text/inheritance.html
@@ -28,6 +28,8 @@ assert_inherited('text-indent', '0px', '10px');
assert_inherited('text-justify', 'auto', 'inter-character');
assert_inherited('text-transform', 'none', 'uppercase');
assert_inherited('text-wrap', 'wrap', 'nowrap');
+assert_inherited('text-wrap-mode', 'wrap', 'nowrap');
+assert_inherited('text-wrap-style', 'auto', 'balance');
assert_inherited('white-space', 'normal', 'pre-wrap');
assert_inherited('white-space-collapse', 'collapse', 'preserve');
assert_inherited('word-break', 'normal', 'break-all');
diff --git a/tests/wpt/tests/css/css-text/parsing/text-wrap-computed.html b/tests/wpt/tests/css/css-text/parsing/text-wrap-computed.html
new file mode 100644
index 00000000000..772f0abf4d9
--- /dev/null
+++ b/tests/wpt/tests/css/css-text/parsing/text-wrap-computed.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Text: getComputedStyle().textWrap</title>
+<link rel="author" title="Tim Nguyen" href="https://github.com/nt1m">
+<link rel="help" href="https://drafts.csswg.org/css-text-4/#text-wrap">
+<meta name="assert" content="text-wrap computed value is '<text-wrap-mode> || <text-wrap-style>'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/computed-testcommon.js"></script>
+</head>
+<body>
+<div id="target"></div>
+<script>
+test_computed_value("text-wrap", "wrap");
+test_computed_value("text-wrap", "nowrap");
+
+test_computed_value("text-wrap", "auto", "wrap");
+test_computed_value("text-wrap", "balance");
+test_computed_value("text-wrap", "stable");
+test_computed_value("text-wrap", "pretty");
+
+test_computed_value("text-wrap", "wrap auto", "wrap");
+test_computed_value("text-wrap", "wrap balance", "balance");
+test_computed_value("text-wrap", "wrap pretty", "pretty");
+test_computed_value("text-wrap", "wrap stable", "stable");
+test_computed_value("text-wrap", "auto wrap", "wrap");
+test_computed_value("text-wrap", "balance wrap", "balance");
+test_computed_value("text-wrap", "pretty wrap", "pretty");
+test_computed_value("text-wrap", "stable wrap", "stable");
+
+test_computed_value("text-wrap", "nowrap auto", "nowrap");
+test_computed_value("text-wrap", "nowrap balance");
+test_computed_value("text-wrap", "nowrap pretty");
+test_computed_value("text-wrap", "nowrap stable");
+test_computed_value("text-wrap", "auto nowrap", "nowrap");
+test_computed_value("text-wrap", "balance nowrap", "nowrap balance");
+test_computed_value("text-wrap", "pretty nowrap", "nowrap pretty");
+test_computed_value("text-wrap", "stable nowrap", "nowrap stable");
+</script>
+</body>
+</html>
diff --git a/tests/wpt/tests/css/css-text/parsing/text-wrap-mode-computed.html b/tests/wpt/tests/css/css-text/parsing/text-wrap-mode-computed.html
new file mode 100644
index 00000000000..35e082b6474
--- /dev/null
+++ b/tests/wpt/tests/css/css-text/parsing/text-wrap-mode-computed.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Text: getComputedStyle().textWrapMode</title>
+<link rel="author" title="Tim Nguyen" href="https://github.com/nt1m">
+<link rel="help" href="https://drafts.csswg.org/css-text-4/#text-wrap-mode">
+<meta name="assert" content="text-wrap-mode computed value is wrap | nowrap">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/computed-testcommon.js"></script>
+</head>
+<body>
+<div id="target"></div>
+<script>
+test_computed_value("text-wrap-mode", "wrap");
+test_computed_value("text-wrap-mode", "nowrap");
+</script>
+</body>
+</html>
diff --git a/tests/wpt/tests/css/css-text/parsing/text-wrap-mode-invalid.html b/tests/wpt/tests/css/css-text/parsing/text-wrap-mode-invalid.html
new file mode 100644
index 00000000000..d63c1901c11
--- /dev/null
+++ b/tests/wpt/tests/css/css-text/parsing/text-wrap-mode-invalid.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Text Module Test: parsing text-wrap-mode with invalid values</title>
+<link rel="author" title="Tim Nguyen" href="https://github.com/nt1m">
+<link rel="help" href="https://drafts.csswg.org/css-text-4/#text-wrap-mode">
+<meta name="assert" content="text-wrap-mode supports only the grammar '<text-wrap-mode>'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_invalid_value("text-wrap-mode", "auto");
+test_invalid_value("text-wrap-mode", "normal");
+test_invalid_value("text-wrap-mode", "none");
+test_invalid_value("text-wrap-mode", "balance");
+test_invalid_value("text-wrap-mode", "pretty");
+test_invalid_value("text-wrap-mode", "stable");
+test_invalid_value("text-wrap-mode", "wrap stable");
+test_invalid_value("text-wrap-mode", "nowrap stable");
+test_invalid_value("text-wrap-mode", "wrap auto");
+test_invalid_value("text-wrap-mode", "balance balance");
+test_invalid_value("text-wrap-mode", "pretty pretty");
+test_invalid_value("text-wrap-mode", "stable stable");
+test_invalid_value("text-wrap-mode", "wrap nowrap");
+test_invalid_value("text-wrap-mode", "pretty balance");
+test_invalid_value("text-wrap-mode", "balance stable");
+test_invalid_value("text-wrap-mode", "stable pretty");
+test_invalid_value("text-wrap-mode", "delicious wrap");
+test_invalid_value("text-wrap-mode", "5px");
+</script>
+</body>
+</html>
diff --git a/tests/wpt/tests/css/css-text/parsing/text-wrap-mode-valid.html b/tests/wpt/tests/css/css-text/parsing/text-wrap-mode-valid.html
new file mode 100644
index 00000000000..5dde8b377fb
--- /dev/null
+++ b/tests/wpt/tests/css/css-text/parsing/text-wrap-mode-valid.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Text Module Test: parsing text-wrap-mode with valid values</title>
+<link rel="author" title="Tim Nguyen" href="https://github.com/nt1m">
+<link rel="help" href="https://drafts.csswg.org/css-text-4/#text-wrap-mode">
+<meta name="assert" content="text-wrap-mode supports the full grammar.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_valid_value("text-wrap-mode", "wrap");
+test_valid_value("text-wrap-mode", "nowrap");
+
+test_valid_value("text-wrap-mode", "initial");
+test_valid_value("text-wrap-mode", "inherit");
+test_valid_value("text-wrap-mode", "unset");
+test_valid_value("text-wrap-mode", "revert");
+test_valid_value("text-wrap-mode", "revert-layer");
+</script>
+</body>
+</html>
diff --git a/tests/wpt/tests/css/css-text/parsing/text-wrap-style-computed.html b/tests/wpt/tests/css/css-text/parsing/text-wrap-style-computed.html
new file mode 100644
index 00000000000..0a4a22d9c5f
--- /dev/null
+++ b/tests/wpt/tests/css/css-text/parsing/text-wrap-style-computed.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Text: getComputedStyle().textWrapStyle</title>
+<link rel="author" title="Tim Nguyen" href="https://github.com/nt1m">
+<link rel="help" href="https://drafts.csswg.org/css-text-4/#text-wrap-style">
+<meta name="assert" content="text-wrap-style computed value is auto | balance | pretty | stable">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/computed-testcommon.js"></script>
+</head>
+<body>
+<div id="target"></div>
+<script>
+test_computed_value("text-wrap-style", "auto");
+test_computed_value("text-wrap-style", "balance");
+test_computed_value("text-wrap-style", "pretty");
+test_computed_value("text-wrap-style", "stable");
+</script>
+</body>
+</html>
diff --git a/tests/wpt/tests/css/css-text/parsing/text-wrap-style-invalid.html b/tests/wpt/tests/css/css-text/parsing/text-wrap-style-invalid.html
new file mode 100644
index 00000000000..dcda82e465d
--- /dev/null
+++ b/tests/wpt/tests/css/css-text/parsing/text-wrap-style-invalid.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Text Module Test: parsing text-wrap-style with invalid values</title>
+<link rel="author" title="Tim Nguyen" href="https://github.com/nt1m">
+<link rel="help" href="https://drafts.csswg.org/css-text-4/#text-wrap-style">
+<meta name="assert" content="text-wrap-style supports only the grammar '<text-wrap-style>'.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_invalid_value("text-wrap-style", "normal");
+test_invalid_value("text-wrap-style", "none");
+test_invalid_value("text-wrap-style", "wrap");
+test_invalid_value("text-wrap-style", "nowrap");
+test_invalid_value("text-wrap-style", "wrap wrap");
+test_invalid_value("text-wrap-style", "nowrap nowrap");
+test_invalid_value("text-wrap-style", "wrap nowrap");
+test_invalid_value("text-wrap-style", "pretty balance");
+test_invalid_value("text-wrap-style", "balance stable");
+test_invalid_value("text-wrap-style", "stable pretty");
+test_invalid_value("text-wrap-style", "delicious wrap");
+test_invalid_value("text-wrap-style", "5px");
+</script>
+</body>
+</html>
diff --git a/tests/wpt/tests/css/css-text/parsing/text-wrap-style-valid.html b/tests/wpt/tests/css/css-text/parsing/text-wrap-style-valid.html
new file mode 100644
index 00000000000..b3ca09ef2c6
--- /dev/null
+++ b/tests/wpt/tests/css/css-text/parsing/text-wrap-style-valid.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Text Module Test: parsing text-wrap-style with valid values</title>
+<link rel="author" title="Tim Nguyen" href="https://github.com/nt1m">
+<link rel="help" href="https://drafts.csswg.org/css-text-4/#text-wrap-style">
+<meta name="assert" content="text-wrap-style supports the full grammar.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_valid_value("text-wrap-style", "auto");
+test_valid_value("text-wrap-style", "balance");
+test_valid_value("text-wrap-style", "pretty");
+test_valid_value("text-wrap-style", "stable");
+
+test_valid_value("text-wrap-style", "initial");
+test_valid_value("text-wrap-style", "inherit");
+test_valid_value("text-wrap-style", "unset");
+test_valid_value("text-wrap-style", "revert");
+test_valid_value("text-wrap-style", "revert-layer");
+</script>
+</body>
+</html>
diff --git a/tests/wpt/tests/css/css-values/round-mod-rem-computed.html b/tests/wpt/tests/css/css-values/round-mod-rem-computed.html
index 320ab4a11a9..eb6dfe4e8ce 100644
--- a/tests/wpt/tests/css/css-values/round-mod-rem-computed.html
+++ b/tests/wpt/tests/css/css-values/round-mod-rem-computed.html
@@ -155,6 +155,10 @@ test_math_used('calc(round(1px + 0%, 1px + 0%))', '1px');
test_math_used('calc(mod(3px + 0%, 2px + 0%))', '1px');
test_math_used('calc(rem(3px + 0%, 2px + 0%))', '1px');
+test_math_used('round(1px + 0%, 1px)', '1px');
+test_math_used('mod(3px + 0%, 2px)', '1px');
+test_math_used('rem(3px + 0%, 2px)', '1px');
+
// In round(A, B), if B is 0, the result is NaN. If A and B are both infinite, the result is NaN.
// In mod(A, B) or rem(A, B), if B is 0, the result is NaN. If A is infinite, the result is NaN.
for (let operator of ['round', 'mod', 'rem']) {
diff --git a/tests/wpt/tests/css/cssom-view/checkVisibility.html b/tests/wpt/tests/css/cssom-view/checkVisibility.html
index c0146dc14e1..c7bd5b69686 100644
--- a/tests/wpt/tests/css/cssom-view/checkVisibility.html
+++ b/tests/wpt/tests/css/cssom-view/checkVisibility.html
@@ -141,4 +141,10 @@ test(() => {
cvhiddenwithupdate.getBoundingClientRect();
assert_true(cvhiddenwithupdate.checkVisibility());
}, 'checkVisibility on content-visibility:hidden element after forced layout update.');
+
+test(() => {
+ document.documentElement.style.contentVisibility = "hidden";
+ assert_true(document.documentElement.checkVisibility());
+ document.documentElement.style.removeProperty("content-visibility");
+}, 'checkVisibility on root element with content-visibility: hidden returns true.');
</script>
diff --git a/tests/wpt/tests/css/cssom/insert-dir-rule-crash.html b/tests/wpt/tests/css/cssom/insert-dir-rule-crash.html
new file mode 100644
index 00000000000..6cffa0c62a5
--- /dev/null
+++ b/tests/wpt/tests/css/cssom/insert-dir-rule-crash.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<title>CSSOM Test: Chrome crash inserting :dir rule</title>
+<link rel="help" href="https://crbug.com/1486351">
+<p>PASS if no crash.</p>
+<style id="sheet"> </style>
+<div id="host"></div>
+<script>
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = "<slot></slot>";
+ host.offsetTop;
+ host.innerHTML = "<span>Green</span>";
+ sheet.sheet.insertRule("html:dir(ltr) { color: green; }");
+ document.fonts.size();
+</script>
diff --git a/tests/wpt/tests/css/selectors/dir-pseudo-on-input-element.html b/tests/wpt/tests/css/selectors/dir-pseudo-on-input-element.html
index db528d4079b..f4a0de193a0 100644
--- a/tests/wpt/tests/css/selectors/dir-pseudo-on-input-element.html
+++ b/tests/wpt/tests/css/selectors/dir-pseudo-on-input-element.html
@@ -84,7 +84,7 @@ test(() => {
document.body.removeChild(container);
}, 'input element whose type attribute is in the telephone state in a RTL block');
-for (let type of ['text', 'search', 'url', 'email']) {
+for (const type of ['password', 'text', 'search', 'url', 'email', 'submit', 'reset', 'button']) {
test(() => {
const input = document.createElement('input');
input.type = type;
@@ -143,7 +143,7 @@ test(() => {
assert_true(input.matches(':dir(rtl)'));
// Changing to a different type that does't use value causes the bidi rule to no longer apply.
- input.type = 'password';
+ input.type = 'radio';
assert_true(input.matches(':dir(ltr)'));
assert_false(input.matches(':dir(rtl)'));
@@ -153,8 +153,7 @@ test(() => {
assert_true(input.matches(':dir(rtl)'));
}, 'dynamic changes to type of input elements affect whether value is used for dir=auto');
-for (let type of ['password', 'date', 'time', 'number', 'range', 'color',
- 'checkbox', 'radio', 'submit', 'image', 'reset', 'button']) {
+for (const type of ['date', 'time', 'number', 'range', 'color', 'checkbox', 'radio', 'image']) {
test(() => {
const input = document.createElement('input');
input.type = type;
diff --git a/tests/wpt/tests/domxpath/001.html b/tests/wpt/tests/domxpath/001.html
deleted file mode 100644
index 4931417af30..00000000000
--- a/tests/wpt/tests/domxpath/001.html
+++ /dev/null
@@ -1,60 +0,0 @@
-<!doctype html>
-<meta charset="utf8">
-<title>XPath in text/html: elements</title>
-<link rel="help" href="http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#Interfaces">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<body>
-<div id="log"><span></span></div>
-<div><span></span></div>
-<dØdd></dØdd>
-<svg>
-<path />
-<path />
-</svg>
-
-<script>
-function test_xpath_succeeds(path, expected, resolver) {
- resolver = resolver ? resolver : null;
- var res = document.evaluate(path, document, resolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
- actual = [];
- for (var i=0;;i++) {
- var node = res.snapshotItem(i);
- if (node === null) {
- break;
- }
- actual.push(node);
- }
- assert_array_equals(actual, expected);
-}
-
-function test_xpath_throws(path, error_code, resolver) {
- resolver = resolver ? resolver : null;
- assert_throws_dom(error_code, function() {document.evaluate(path, document, resolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null)})
-}
-
-function ns_resolver(x) {
- map = {"html":"http://www.w3.org/1999/xhtml",
- "svg":"http://www.w3.org/2000/svg",
- "math":"http://www.w3.org/1998/Math/MathML"};
- var rv = map.hasOwnProperty(x) ? map[x] : null;
- return rv;
-}
-
-generate_tests(test_xpath_succeeds,[
- ["HTML elements no namespace prefix", "//div", document.getElementsByTagName("div")],
- ["HTML elements namespace prefix", "//html:div", document.getElementsByTagName("div"), ns_resolver],
- ["HTML elements mixed use of prefix", "//html:div/span", document.getElementsByTagName("span"), ns_resolver],
- ["SVG elements no namespace prefix", "//path", []],
- ["SVG elements namespace prefix", "//svg:path", document.getElementsByTagName("path"), ns_resolver],
- ["HTML elements mixed case", "//DiV", document.getElementsByTagName("div")],
- ["SVG elements mixed case selector", "//svg:PatH", [], ns_resolver],
- ["Non-ascii HTML element", "//dØdd", document.getElementsByTagName("dØdd"), ns_resolver],
- ["Non-ascii HTML element2", "//dødd", [], ns_resolver],
- ["Non-ascii HTML element3", "//DØDD", document.getElementsByTagName("dØdd"), ns_resolver]
-])
-
-generate_tests(test_xpath_throws, [
- ["Throw with invalid prefix", "//invalid:path", "NAMESPACE_ERR"],
-])
-</script>
diff --git a/tests/wpt/tests/domxpath/002.html b/tests/wpt/tests/domxpath/002.html
deleted file mode 100644
index c5c1fcc5292..00000000000
--- a/tests/wpt/tests/domxpath/002.html
+++ /dev/null
@@ -1,60 +0,0 @@
-<!doctype html>
-<meta charset="utf8">
-<title>XPath in text/html: attributes</title>
-<link rel="help" href="http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#Interfaces">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<body>
-<div id="log" nonÄsciiAttribute><span></span></div>
-<svg xmlns="http://www.w3.org/2000/svg", xmlns:xlink="http://www.w3.org/1999/xlink">
-<path id="a" refx />
-<path id="b" nonÄscii xlink:href />
-</svg>
-
-<script>
-function test_xpath_succeeds(path, expected, resolver) {
- resolver = resolver ? resolver : null;
- var res = document.evaluate(path, document, resolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
- actual = [];
- for (var i=0;;i++) {
- var node = res.snapshotItem(i);
- if (node === null) {
- break;
- }
- actual.push(node);
- }
- assert_array_equals(actual, expected);
-}
-
-function test_xpath_throws(path, error_code, resolver) {
- resolver = resolver ? resolver : null;
- assert_throws_dom(error_code, function() {document.evaluate(path, document, resolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null)})
-}
-
-function ns_resolver(x) {
- map = {"html":"http://www.w3.org/1999/xhtml",
- "svg":"http://www.w3.org/2000/svg",
- "math":"http://www.w3.org/1998/Math/MathML",
- "xlink":"http://www.w3.org/1999/xlink"};
- var rv = map.hasOwnProperty(x) ? map[x] : null;
- return rv;
-}
-
-generate_tests(test_xpath_succeeds,[
- ["Select html element based on attribute", "//div[@id='log']", [document.getElementById("log")]],
- ["Select html element based on attribute mixed case", "//div[@Id='log']", [document.getElementById("log")]],
- ["Select both HTML and SVG elements based on attribute", "//*[@id]", [document.getElementById("log")].concat(Array.prototype.slice.call(document.getElementsByTagName("path")))],
- ["Select HTML element with non-ascii attribute 1", "//*[@nonÄsciiattribute]", [document.getElementById("log")]],
- ["Select HTML element with non-ascii attribute 2", "//*[@nonäsciiattribute]", []],
- ["Select HTML element with non-ascii attribute 3", "//*[@nonÄsciiAttribute]", [document.getElementById("log")]],
- ["Select SVG element based on mixed case attribute", "//svg:path[@Id]", [], ns_resolver],
- ["Select both HTML and SVG elements based on mixed case attribute", "//*[@Id]", [document.getElementById("log")]],
- ["Select SVG elements with refX attribute", "//*[@refX]", [document.getElementById("a")]],
- ["Select SVG elements with refX attribute incorrect case", "//*[@Refx]", []],
- ["Select SVG elements with refX attribute lowercase", "//*[@refx]", []],
- ["Select SVG element with non-ascii attribute 1", "//*[@nonÄscii]", [document.getElementById("b")]],
- ["Select SVG element with non-ascii attribute 2", "//*[@nonäscii]", []],
- ["xmlns attribute", "//*[@xmlns]", []],
- ["svg element with XLink attribute", "//*[@xlink:href]", [document.getElementById("b")], ns_resolver]
-])
-</script>
diff --git a/tests/wpt/tests/domxpath/text-html-attributes.html b/tests/wpt/tests/domxpath/text-html-attributes.html
new file mode 100644
index 00000000000..2157dcd2d68
--- /dev/null
+++ b/tests/wpt/tests/domxpath/text-html-attributes.html
@@ -0,0 +1,102 @@
+<!doctype html>
+<meta charset="utf8">
+<title>XPath in text/html: attributes</title>
+<link rel="help" href="http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#Interfaces">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body>
+<div id="log" nonÄsciiAttribute><span></span></div>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+<path id="a" refx />
+<path id="b" nonÄscii xlink:href />
+</svg>
+
+<script>
+function test_xpath_succeeds(path, expected, resolver) {
+ resolver = resolver ? resolver : null;
+ var res = document.evaluate(path, document, resolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
+ actual = [];
+ for (var i=0;;i++) {
+ var node = res.snapshotItem(i);
+ if (node === null) {
+ break;
+ }
+ actual.push(node);
+ }
+ assert_array_equals(actual, expected);
+}
+
+function test_xpath_throws(path, error_code, resolver) {
+ resolver = resolver ? resolver : null;
+ assert_throws_dom(error_code, function() {document.evaluate(path, document, resolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null)})
+}
+
+function ns_resolver(x) {
+ map = {"html":"http://www.w3.org/1999/xhtml",
+ "svg":"http://www.w3.org/2000/svg",
+ "math":"http://www.w3.org/1998/Math/MathML",
+ "xlink":"http://www.w3.org/1999/xlink"};
+ var rv = map.hasOwnProperty(x) ? map[x] : null;
+ return rv;
+}
+
+test(function() {
+ test_xpath_succeeds("//div[@id='log']", [document.getElementById("log")]);
+}, "Select html element based on attribute");
+
+test(function() {
+ test_xpath_succeeds("//div[@Id='log']", [document.getElementById("log")]);
+}, "Select html element based on attribute mixed case");
+
+test(function() {
+ test_xpath_succeeds("//*[@id]", [document.getElementById("log")].concat(Array.prototype.slice.call(document.getElementsByTagName("path"))));
+}, "Select both HTML and SVG elements based on attribute");
+
+test(function() {
+ test_xpath_succeeds("//*[@nonÄsciiattribute]", [document.getElementById("log")]);
+}, "Select HTML element with non-ascii attribute 1");
+
+test(function() {
+ test_xpath_succeeds("//*[@nonäsciiattribute]", []);
+}, "Select HTML element with non-ascii attribute 2");
+
+test(function() {
+ test_xpath_succeeds("//*[@nonÄsciiAttribute]", [document.getElementById("log")]);
+}, "Select HTML element with non-ascii attribute 3");
+
+test(function() {
+ test_xpath_succeeds("//svg:path[@Id]", [], ns_resolver);
+}, "Select SVG element based on mixed case attribute");
+
+test(function() {
+ test_xpath_succeeds("//*[@Id]", [document.getElementById("log")]);
+}, "Select both HTML and SVG elements based on mixed case attribute");
+
+test(function() {
+ test_xpath_succeeds("//*[@refX]", [document.getElementById("a")]);
+}, "Select SVG elements with refX attribute");
+
+test(function() {
+ test_xpath_succeeds("//*[@Refx]", []);
+}, "Select SVG elements with refX attribute incorrect case");
+
+test(function() {
+ test_xpath_succeeds("//*[@refx]", []);
+}, "Select SVG elements with refX attribute lowercase");
+
+test(function() {
+ test_xpath_succeeds("//*[@nonÄscii]", [document.getElementById("b")]);
+}, "Select SVG element with non-ascii attribute 1");
+
+test(function() {
+ test_xpath_succeeds("//*[@nonäscii]", []);
+}, "Select SVG element with non-ascii attribute 2");
+
+test(function() {
+ test_xpath_succeeds("//*[@xmlns]", []);
+}, "xmlns attribute");
+
+test(function() {
+ test_xpath_succeeds("//*[@xlink:href]", [document.getElementById("b")], ns_resolver);
+}, "svg element with XLink attribute");
+</script>
diff --git a/tests/wpt/tests/domxpath/text-html-elements.html b/tests/wpt/tests/domxpath/text-html-elements.html
new file mode 100644
index 00000000000..b895323fbad
--- /dev/null
+++ b/tests/wpt/tests/domxpath/text-html-elements.html
@@ -0,0 +1,87 @@
+<!doctype html>
+<meta charset="utf8">
+<title>XPath in text/html: elements</title>
+<link rel="help" href="http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#Interfaces">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body>
+<div id="log"><span></span></div>
+<div><span></span></div>
+<dØdd></dØdd>
+<svg>
+<path />
+<path />
+</svg>
+
+<script>
+function test_xpath_succeeds(path, expected, resolver) {
+ resolver = resolver ? resolver : null;
+ var res = document.evaluate(path, document, resolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
+ actual = [];
+ for (var i=0;;i++) {
+ var node = res.snapshotItem(i);
+ if (node === null) {
+ break;
+ }
+ actual.push(node);
+ }
+ assert_array_equals(actual, expected);
+}
+
+function test_xpath_throws(path, error_code, resolver) {
+ resolver = resolver ? resolver : null;
+ assert_throws_dom(error_code, function() {document.evaluate(path, document, resolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null)})
+}
+
+function ns_resolver(x) {
+ map = {"html":"http://www.w3.org/1999/xhtml",
+ "svg":"http://www.w3.org/2000/svg",
+ "math":"http://www.w3.org/1998/Math/MathML"};
+ var rv = map.hasOwnProperty(x) ? map[x] : null;
+ return rv;
+}
+
+test(function() {
+ test_xpath_succeeds("//div", document.getElementsByTagName("div"));
+}, "HTML elements no namespace prefix");
+
+test(function() {
+ test_xpath_succeeds("//html:div", document.getElementsByTagName("div"), ns_resolver);
+}, "HTML elements namespace prefix");
+
+test(function() {
+ test_xpath_succeeds("//html:div/span", document.getElementsByTagName("span"), ns_resolver);
+}, "HTML elements mixed use of prefix");
+
+test(function() {
+ test_xpath_succeeds("//path", []);
+}, "SVG elements no namespace prefix");
+
+test(function() {
+ test_xpath_succeeds("//svg:path", document.getElementsByTagName("path"), ns_resolver);
+}, "SVG elements namespace prefix");
+
+test(function() {
+ test_xpath_succeeds("//DiV", document.getElementsByTagName("div"));
+}, "HTML elements mixed case");
+
+test(function() {
+ test_xpath_succeeds("//svg:PatH", [], ns_resolver);
+}, "SVG elements mixed case selector");
+
+test(function() {
+ test_xpath_succeeds("//dØdd", document.getElementsByTagName("dØdd"), ns_resolver);
+}, "Non-ascii HTML element");
+
+test(function() {
+ test_xpath_succeeds("//dødd", [], ns_resolver);
+}, "Non-ascii HTML element2");
+
+test(function() {
+ test_xpath_succeeds("//DØDD", document.getElementsByTagName("dØdd"), ns_resolver);
+}, "Non-ascii HTML element3");
+
+test(function() {
+ test_xpath_throws("//invalid:path", "NAMESPACE_ERR");
+}, "Throw with invalid prefix");
+</script>
diff --git a/tests/wpt/tests/editing/data/formatblock.js b/tests/wpt/tests/editing/data/formatblock.js
index 64e0d11d594..0161e4da01b 100644
--- a/tests/wpt/tests/editing/data/formatblock.js
+++ b/tests/wpt/tests/editing/data/formatblock.js
@@ -147,14 +147,14 @@ var browserTests = [
{"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"div"]}],
["<blockquote>[foobar]</blockquote>",
[["defaultparagraphseparator","div"],["formatblock","<div>"]],
- "<blockquote><div>[foobar]</div></blockquote>",
+ "<div>[foobar]</div>",
[true,true],
- {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"div"]}],
+ {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"blockquote",false,false,"div"]}],
["<blockquote>[foobar]</blockquote>",
[["defaultparagraphseparator","p"],["formatblock","<div>"]],
- "<blockquote><div>[foobar]</div></blockquote>",
+ "<div>[foobar]</div>",
[true,true],
- {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"div"]}],
+ {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"blockquote",false,false,"div"]}],
["<h1>[foobar]</h1>",
[["defaultparagraphseparator","div"],["formatblock","<div>"]],
"<div>[foobar]</div>",
@@ -239,12 +239,12 @@ var browserTests = [
[["defaultparagraphseparator","div"],["formatblock","<div>"]],
"<div>[foo</div><div>bar]</div>",
[true,true],
- {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[true,false,"dt",false,false,"div"]}],
+ {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[true,false,"dl",false,false,"div"]}],
["<dl><dt>[foo<dd>bar]</dl>",
[["defaultparagraphseparator","p"],["formatblock","<div>"]],
"<div>[foo</div><div>bar]</div>",
[true,true],
- {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[true,false,"dt",false,false,"div"]}],
+ {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[true,false,"dl",false,false,"div"]}],
["<ol><li>[foobar]</ol>",
[["defaultparagraphseparator","div"],["formatblock","<div>"]],
"<ol><li><div>[foobar]</div></li></ol>",
@@ -287,14 +287,14 @@ var browserTests = [
{"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"pre",false,false,"div"]}],
["<article>[foobar]</article>",
[["defaultparagraphseparator","div"],["formatblock","<div>"]],
- "<article><div>[foobar]</div></article>",
+ "<div>[foobar]</div>",
[true,true],
- {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"div"]}],
+ {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"article",false,false,"div"]}],
["<article>[foobar]</article>",
[["defaultparagraphseparator","p"],["formatblock","<div>"]],
- "<article><div>[foobar]</div></article>",
+ "<div>[foobar]</div>",
[true,true],
- {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"div"]}],
+ {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"article",false,false,"div"]}],
["<ins>[foobar]</ins>",
[["defaultparagraphseparator","div"],["formatblock","<div>"]],
"<div><ins>[foobar]</ins></div>",
@@ -482,14 +482,14 @@ var browserTests = [
{"formatblock":[false,false,"p",false,false,"p"]}],
["<blockquote>[foobar]</blockquote>",
[["defaultparagraphseparator","div"],["formatblock","<p>"]],
- "<blockquote><p>[foobar]</p></blockquote>",
+ "<p>[foobar]</p>",
[true,true],
- {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"p"]}],
+ {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"blockquote",false,false,"p"]}],
["<blockquote>[foobar]</blockquote>",
[["defaultparagraphseparator","p"],["formatblock","<p>"]],
- "<blockquote><p>[foobar]</p></blockquote>",
+ "<p>[foobar]</p>",
[true,true],
- {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"p"]}],
+ {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"blockquote",false,false,"p"]}],
["<h1>[foobar]</h1>",
[["defaultparagraphseparator","div"],["formatblock","<p>"]],
"<p>[foobar]</p>",
@@ -574,12 +574,12 @@ var browserTests = [
[["defaultparagraphseparator","div"],["formatblock","<p>"]],
"<p>[foo</p><p>bar]</p>",
[true,true],
- {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[true,false,"dt",false,false,"p"]}],
+ {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[true,false,"dl",false,false,"p"]}],
["<dl><dt>[foo<dd>bar]</dl>",
[["defaultparagraphseparator","p"],["formatblock","<p>"]],
"<p>[foo</p><p>bar]</p>",
[true,true],
- {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[true,false,"dt",false,false,"p"]}],
+ {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[true,false,"dl",false,false,"p"]}],
["<ol><li>[foobar]</ol>",
[["defaultparagraphseparator","div"],["formatblock","<p>"]],
"<ol><li><p>[foobar]</p></li></ol>",
@@ -622,34 +622,34 @@ var browserTests = [
{"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"pre",false,false,"p"]}],
["<listing>[foobar]</listing>",
[["defaultparagraphseparator","div"],["formatblock","<p>"]],
- "<p>[foobar]</p>",
+ "<p><listing>[foobar]</listing></p>",
[true,true],
{"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"p"]}],
["<listing>[foobar]</listing>",
[["defaultparagraphseparator","p"],["formatblock","<p>"]],
- "<p>[foobar]</p>",
+ "<p><listing>[foobar]</listing></p>",
[true,true],
{"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"p"]}],
["<xmp>[foobar]</xmp>",
[["defaultparagraphseparator","div"],["formatblock","<p>"]],
- "<p>[foobar]</p>",
+ "<p><xmp>[foobar]</xmp></p>",
[true,true],
{"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"p"]}],
["<xmp>[foobar]</xmp>",
[["defaultparagraphseparator","p"],["formatblock","<p>"]],
- "<p>[foobar]</p>",
+ "<p><xmp>[foobar]</xmp></p>",
[true,true],
{"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"p"]}],
["<article>[foobar]</article>",
[["defaultparagraphseparator","div"],["formatblock","<p>"]],
- "<article><p>[foobar]</p></article>",
+ "<p>[foobar]</p>",
[true,true],
- {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"p"]}],
+ {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"article",false,false,"p"]}],
["<article>[foobar]</article>",
[["defaultparagraphseparator","p"],["formatblock","<p>"]],
- "<article><p>[foobar]</p></article>",
+ "<p>[foobar]</p>",
[true,true],
- {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"p"]}],
+ {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"article",false,false,"p"]}],
["<ins>[foobar]</ins>",
[["defaultparagraphseparator","div"],["formatblock","<p>"]],
"<p><ins>[foobar]</ins></p>",
@@ -693,43 +693,46 @@ var browserTests = [
["<blockquote>[foo]</blockquote><p>extra",
[["formatblock","<blockquote>"]],
"<blockquote>[foo]</blockquote><p>extra</p>",
- [false],
- {"formatblock":[false,false,"",false,false,""]}],
+ [true],
+ {"formatblock":[false,false,"blockquote",false,false,"blockquote"]}],
["<blockquote><p>[foo]<p>bar</blockquote><p>extra",
[["formatblock","<blockquote>"]],
- "<blockquote><p>[foo]</p><p>bar</p></blockquote><p>extra</p>",
- [false],
- {"formatblock":[false,false,"p",false,false,"p"]}],
+ "<blockquote><blockquote>[foo]</blockquote><p>bar</p></blockquote><p>extra</p>",
+ [true],
+ {"formatblock":[false,false,"p",false,false,"blockquote"]}],
["[foo]<blockquote>bar</blockquote><p>extra",
[["formatblock","<blockquote>"]],
- "[foo]<blockquote>bar</blockquote><p>extra</p>",
- [false],
- {"formatblock":[false,false,"",false,false,""]}],
+ "<blockquote>[foo]</blockquote><blockquote>bar</blockquote><p>extra</p>",
+ [true],
+ {"formatblock":[false,false,"",false,false,"blockquote"]}],
["<p>[foo<p>bar]<p>baz",
[["formatblock","<blockquote>"]],
- "<p>[foo</p><p>bar]</p><p>baz</p>",
- [false],
- {"formatblock":[false,false,"p",false,false,"p"]}],
+ [
+ "<blockquote>[foo<br>bar]</blockquote><p>baz</p>",
+ "<blockquote>[foo</blockquote><blockquote>bar]</blockquote><p>baz</p>",
+ ]
+ [true],
+ {"formatblock":[false,false,"",false,false,"blockquote"]}],
["<section>[foo]</section>",
[["formatblock","<blockquote>"]],
- "<section>[foo]</section>",
- [false],
- {"formatblock":[false,false,"",false,false,""]}],
+ "<blockquote>[foo]</blockquote>",
+ [true],
+ {"formatblock":[false,false,"section",false,false,"blockquote"]}],
["<section><p>[foo]</section>",
[["formatblock","<blockquote>"]],
- "<section><p>[foo]</p></section>",
- [false],
- {"formatblock":[false,false,"p",false,false,"p"]}],
+ "<section><blockquote>[foo]</blockquote></section>",
+ [true],
+ {"formatblock":[false,false,"p",false,false,"blockquote"]}],
["<section><hgroup><h1>[foo]</h1><h2>bar</h2></hgroup><p>baz</section>",
[["formatblock","<blockquote>"]],
- "<section><hgroup><h1>[foo]</h1><h2>bar</h2></hgroup><p>baz</p></section>",
- [false],
- {"formatblock":[false,false,"h1",false,false,"h1"]}],
+ "<section><hgroup><blockquote>[foo]</blockquote><h2>bar</h2></hgroup><p>baz</p></section>",
+ [true],
+ {"formatblock":[false,false,"h1",false,false,"blockquote"]}],
["<section>[foo]</section>",
[["formatblock","<article>"]],
- "<section>[foo]</section>",
- [false],
- {"formatblock":[false,false,"",false,false,""]}],
+ "<article>[foo]</article>",
+ [true],
+ {"formatblock":[false,false,"section",false,false,"article"]}],
["<div>[foobar]</div>",
[["defaultparagraphseparator","div"],["formatblock","<address>"]],
"<address>[foobar]</address>",
@@ -742,14 +745,14 @@ var browserTests = [
{"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"div",false,false,"address"]}],
["<div>[foobar]</div>",
[["formatblock","<article>"]],
- "<div>[foobar]</div>",
- [false],
- {"formatblock":[false,false,"div",false,false,"div"]}],
+ "<article>[foobar]</article>",
+ [true],
+ {"formatblock":[false,false,"div",false,false,"article"]}],
["<div>[foobar]</div>",
[["formatblock","<blockquote>"]],
- "<div>[foobar]</div>",
- [false],
- {"formatblock":[false,false,"div",false,false,"div"]}],
+ "<blockquote>[foobar]</blockquote>",
+ [true],
+ {"formatblock":[false,false,"div",false,false,"blockquote"]}],
["<div>[foobar]</div>",
[["defaultparagraphseparator","div"],["formatblock","<dd>"]],
"<dl><dd>[foobar]</dd></dl>",
@@ -882,19 +885,19 @@ var browserTests = [
{"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"address"]}],
["<p>[foobar]</p>",
[["formatblock","<article>"]],
- "<p>[foobar]</p>",
- [false],
- {"formatblock":[false,false,"p",false,false,"p"]}],
+ "<article>[foobar]</article>",
+ [true],
+ {"formatblock":[false,false,"p",false,false,"article"]}],
["<p>[foobar]</p>",
[["formatblock","<aside>"]],
- "<p>[foobar]</p>",
- [false],
- {"formatblock":[false,false,"p",false,false,"p"]}],
+ "<aside>[foobar]</aside>",
+ [true],
+ {"formatblock":[false,false,"p",false,false,"aside"]}],
["<p>[foobar]</p>",
[["formatblock","<blockquote>"]],
- "<p>[foobar]</p>",
- [false],
- {"formatblock":[false,false,"p",false,false,"p"]}],
+ "<blockquote>[foobar]</blockquote>",
+ [true],
+ {"formatblock":[false,false,"p",false,false,"blockquote"]}],
["<p>[foobar]</p>",
[["formatblock","<body>"]],
"<p>[foobar]</p>",
@@ -957,9 +960,9 @@ var browserTests = [
{"formatblock":[false,false,"p",false,false,"p"]}],
["<p>[foobar]</p>",
[["formatblock","<footer>"]],
- "<p>[foobar]</p>",
- [false],
- {"formatblock":[false,false,"p",false,false,"p"]}],
+ "<footer>[foobar]</footer>",
+ [true],
+ {"formatblock":[false,false,"p",false,false,"footer"]}],
["<p>[foobar]</p>",
[["formatblock","<form>"]],
"<p>[foobar]</p>",
@@ -1027,9 +1030,9 @@ var browserTests = [
{"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"h6"]}],
["<p>[foobar]</p>",
[["formatblock","<header>"]],
- "<p>[foobar]</p>",
- [false],
- {"formatblock":[false,false,"p",false,false,"p"]}],
+ "<header>[foobar]</header>",
+ [true],
+ {"formatblock":[false,false,"p",false,false,"header"]}],
["<p>[foobar]</p>",
[["formatblock","<head>"]],
"<p>[foobar]</p>",
@@ -1037,9 +1040,9 @@ var browserTests = [
{"formatblock":[false,false,"p",false,false,"p"]}],
["<p>[foobar]</p>",
[["formatblock","<hgroup>"]],
- "<p>[foobar]</p>",
- [false],
- {"formatblock":[false,false,"p",false,false,"p"]}],
+ "<hgroup>[foobar]</hgroup>",
+ [true],
+ {"formatblock":[false,false,"p",false,false,"hgroup"]}],
["<p>[foobar]</p>",
[["formatblock","<hr>"]],
"<p>[foobar]</p>",
@@ -1072,9 +1075,9 @@ var browserTests = [
{"formatblock":[false,false,"p",false,false,"p"]}],
["<p>[foobar]</p>",
[["formatblock","<nav>"]],
- "<p>[foobar]</p>",
- [false],
- {"formatblock":[false,false,"p",false,false,"p"]}],
+ "<nav>[foobar]</nav>",
+ [true],
+ {"formatblock":[false,false,"p",false,false,"nav"]}],
["<p>[foobar]</p>",
[["formatblock","<ol>"]],
"<p>[foobar]</p>",
@@ -1097,9 +1100,9 @@ var browserTests = [
{"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"pre"]}],
["<p>[foobar]</p>",
[["formatblock","<section>"]],
- "<p>[foobar]</p>",
- [false],
- {"formatblock":[false,false,"p",false,false,"p"]}],
+ "<section>[foobar]</section>",
+ [true],
+ {"formatblock":[false,false,"p",false,false,"section"]}],
["<p>[foobar]</p>",
[["formatblock","<ul>"]],
"<p>[foobar]</p>",
@@ -1117,29 +1120,44 @@ var browserTests = [
{"formatblock":[false,false,"p",false,false,"p"]}],
["<p>[foo<p>bar]",
[["defaultparagraphseparator","div"],["formatblock","<address>"]],
- "<address>[foo<br>bar]</address>",
+ [
+ "<address>[foo<br>bar]</address>",
+ "<address>[foo</address><address>bar]</address>",
+ ],
[true,true],
{"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"p",false,false,"address"]}],
["<p>[foo<p>bar]",
[["defaultparagraphseparator","p"],["formatblock","<address>"]],
- "<address>[foo<br>bar]</address>",
+ [
+ "<address>[foo<br>bar]</address>",
+ "<address>[foo</address><address>bar]</address>",
+ ],
[true,true],
{"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"address"]}],
["<p>[foo<p>bar]",
[["formatblock","<article>"]],
- "<p>[foo</p><p>bar]</p>",
- [false],
- {"formatblock":[false,false,"p",false,false,"p"]}],
+ [
+ "<article>[foo<br>bar]</article>",
+ "<article>[foo</article><article>bar]</article>",
+ ],
+ [true],
+ {"formatblock":[false,false,"p",false,false,"article"]}],
["<p>[foo<p>bar]",
[["formatblock","<aside>"]],
- "<p>[foo</p><p>bar]</p>",
- [false],
- {"formatblock":[false,false,"p",false,false,"p"]}],
+ [
+ "<aside>[foo<br>bar]</aside>",
+ "<aside>[foo</aside><aside>bar]</aside>",
+ ],
+ [true],
+ {"formatblock":[false,false,"p",false,false,"aside"]}],
["<p>[foo<p>bar]",
[["formatblock","<blockquote>"]],
- "<p>[foo</p><p>bar]</p>",
- [false],
- {"formatblock":[false,false,"p",false,false,"p"]}],
+ [
+ "<blockquote>[foo<br>bar]</blockquote>",
+ "<blockquote>[foo</blockquote><blockquote>bar]</blockquote>",
+ ],
+ [true],
+ {"formatblock":[false,false,"p",false,false,"blockquote"]}],
["<p>[foo<p>bar]",
[["formatblock","<body>"]],
"<p>[foo</p><p>bar]</p>",
@@ -1172,12 +1190,18 @@ var browserTests = [
{"formatblock":[false,false,"p",false,false,"p"]}],
["<p>[foo<p>bar]",
[["defaultparagraphseparator","div"],["formatblock","<div>"]],
- "<div>[foo</div><div>bar]</div>",
+ [
+ "<div>[foo<br>bar]</div>",
+ "<div>[foo</div><div>bar]</div>",
+ ],
[true,true],
{"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"p",false,false,"div"]}],
["<p>[foo<p>bar]",
[["defaultparagraphseparator","p"],["formatblock","<div>"]],
- "<div>[foo</div><div>bar]</div>",
+ [
+ "<div>[foo<br>bar]</div>",
+ "<div>[foo</div><div>bar]</div>",
+ ],
[true,true],
{"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"div"]}],
["<p>[foo<p>bar]",
@@ -1212,9 +1236,12 @@ var browserTests = [
{"formatblock":[false,false,"p",false,false,"p"]}],
["<p>[foo<p>bar]",
[["formatblock","<footer>"]],
- "<p>[foo</p><p>bar]</p>",
- [false],
- {"formatblock":[false,false,"p",false,false,"p"]}],
+ [
+ "<footer>[foo<br>bar]</footer>",
+ "<footer>[foo</footer><footer>bar]</footer>",
+ ],
+ [true],
+ {"formatblock":[false,false,"p",false,false,"footer"]}],
["<p>[foo<p>bar]",
[["formatblock","<form>"]],
"<p>[foo</p><p>bar]</p>",
@@ -1222,69 +1249,108 @@ var browserTests = [
{"formatblock":[false,false,"p",false,false,"p"]}],
["<p>[foo<p>bar]",
[["defaultparagraphseparator","div"],["formatblock","<h1>"]],
- "<h1>[foo<br>bar]</h1>",
+ [
+ "<h1>[foo<br>bar]</h1>",
+ "<h1>[foo</h1><h1>bar]</h1>",
+ ],
[true,true],
{"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"p",false,false,"h1"]}],
["<p>[foo<p>bar]",
[["defaultparagraphseparator","p"],["formatblock","<h1>"]],
- "<h1>[foo<br>bar]</h1>",
+ [
+ "<h1>[foo<br>bar]</h1>",
+ "<h1>[foo</h1><h1>bar]</h1>",
+ ],
[true,true],
{"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"h1"]}],
["<p>[foo<p>bar]",
[["defaultparagraphseparator","div"],["formatblock","<h2>"]],
- "<h2>[foo<br>bar]</h2>",
+ [
+ "<h2>[foo<br>bar]</h2>",
+ "<h2>[foo</h2><h2>bar]</h2>",
+ ],
[true,true],
{"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"p",false,false,"h2"]}],
["<p>[foo<p>bar]",
[["defaultparagraphseparator","p"],["formatblock","<h2>"]],
- "<h2>[foo<br>bar]</h2>",
+ [
+ "<h2>[foo<br>bar]</h2>",
+ "<h2>[foo</h2><h2>bar]</h2>",
+ ],
[true,true],
{"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"h2"]}],
["<p>[foo<p>bar]",
[["defaultparagraphseparator","div"],["formatblock","<h3>"]],
- "<h3>[foo<br>bar]</h3>",
+ [
+ "<h3>[foo<br>bar]</h3>",
+ "<h3>[foo</h3><h3>bar]</h3>",
+ ],
[true,true],
{"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"p",false,false,"h3"]}],
["<p>[foo<p>bar]",
[["defaultparagraphseparator","p"],["formatblock","<h3>"]],
- "<h3>[foo<br>bar]</h3>",
+ [
+ "<h3>[foo<br>bar]</h3>",
+ "<h3>[foo</h3><h3>bar]</h3>",
+ ],
[true,true],
{"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"h3"]}],
["<p>[foo<p>bar]",
[["defaultparagraphseparator","div"],["formatblock","<h4>"]],
- "<h4>[foo<br>bar]</h4>",
+ [
+ "<h4>[foo<br>bar]</h4>",
+ "<h4>[foo</h4><h4>bar]</h4>",
+ ],
[true,true],
{"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"p",false,false,"h4"]}],
["<p>[foo<p>bar]",
[["defaultparagraphseparator","p"],["formatblock","<h4>"]],
- "<h4>[foo<br>bar]</h4>",
+ [
+ "<h4>[foo<br>bar]</h4>",
+ "<h4>[foo</h4><h4>bar]</h4>",
+ ],
[true,true],
{"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"h4"]}],
["<p>[foo<p>bar]",
[["defaultparagraphseparator","div"],["formatblock","<h5>"]],
- "<h5>[foo<br>bar]</h5>",
+ [
+ "<h5>[foo<br>bar]</h5>",
+ "<h5>[foo</h5><h5>bar]</h5>",
+ ],
[true,true],
{"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"p",false,false,"h5"]}],
["<p>[foo<p>bar]",
[["defaultparagraphseparator","p"],["formatblock","<h5>"]],
- "<h5>[foo<br>bar]</h5>",
+ [
+ "<h5>[foo<br>bar]</h5>",
+ "<h5>[foo</h5><h5>bar]</h5>",
+ ],
[true,true],
{"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"h5"]}],
["<p>[foo<p>bar]",
[["defaultparagraphseparator","div"],["formatblock","<h6>"]],
- "<h6>[foo<br>bar]</h6>",
+ [
+ "<h6>[foo<br>bar]</h6>",
+ "<h6>[foo</h6><h6>bar]</h6>",
+ ],
[true,true],
{"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"p",false,false,"h6"]}],
["<p>[foo<p>bar]",
[["defaultparagraphseparator","p"],["formatblock","<h6>"]],
- "<h6>[foo<br>bar]</h6>",
+ [
+ "<h6>[foo<br>bar]</h6>",
+ "<h6>[foo</h6><h6>bar]</h6>",
+ ],
[true,true],
{"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"h6"]}],
["<p>[foo<p>bar]",
[["formatblock","<header>"]],
- "<p>[foo</p><p>bar]</p>",
- [false],
- {"formatblock":[false,false,"p",false,false,"p"]}],
+ [
+ "<header>[foo<br>bar]</header>",
+ "<header>[foo</header><header>bar]</header>",
+ ],
+ [true],
+ {"formatblock":[false,false,"p",false,false,"header"]}],
["<p>[foo<p>bar]",
[["formatblock","<head>"]],
"<p>[foo</p><p>bar]</p>",
@@ -1292,9 +1358,12 @@ var browserTests = [
{"formatblock":[false,false,"p",false,false,"p"]}],
["<p>[foo<p>bar]",
[["formatblock","<hgroup>"]],
- "<p>[foo</p><p>bar]</p>",
- [false],
- {"formatblock":[false,false,"p",false,false,"p"]}],
+ [
+ "<hgroup>[foo<br>bar]</hgroup>",
+ "<hgroup>[foo</hgroup><hgroup>bar]</hgroup>",
+ ],
+ [true],
+ {"formatblock":[false,false,"p",false,false,"hgroup"]}],
["<p>[foo<p>bar]",
[["formatblock","<hr>"]],
"<p>[foo</p><p>bar]</p>",
@@ -1327,9 +1396,12 @@ var browserTests = [
{"formatblock":[false,false,"p",false,false,"p"]}],
["<p>[foo<p>bar]",
[["formatblock","<nav>"]],
- "<p>[foo</p><p>bar]</p>",
- [false],
- {"formatblock":[false,false,"p",false,false,"p"]}],
+ [
+ "<nav>[foo<br>bar]</nav>",
+ "<nav>[foo</nav><nav>bar]</nav>",
+ ],
+ [true],
+ {"formatblock":[false,false,"p",false,false,"nav"]}],
["<p>[foo<p>bar]",
[["formatblock","<ol>"]],
"<p>[foo</p><p>bar]</p>",
@@ -1347,7 +1419,10 @@ var browserTests = [
{"formatblock":[false,false,"p",false,false,"p"]}],
["<p>[foo<p>bar]",
[["defaultparagraphseparator","div"],["formatblock","<pre>"]],
- "<pre>[foo<br>bar]</pre>",
+ [
+ "<pre>[foo<br>bar]</pre>",
+ "<pre>[foo</pre><pre>bar]</pre>",
+ ],
[true,true],
{"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"p",false,false,"pre"]}],
["<p>[foo<p>bar]",
@@ -1357,9 +1432,12 @@ var browserTests = [
{"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"p",false,false,"pre"]}],
["<p>[foo<p>bar]",
[["formatblock","<section>"]],
- "<p>[foo</p><p>bar]</p>",
- [false],
- {"formatblock":[false,false,"p",false,false,"p"]}],
+ [
+ "<section>[foo<br>bar]</section>",
+ "<section>[foo</section><section>bar]</section>",
+ ],
+ [true],
+ {"formatblock":[false,false,"p",false,false,"section"]}],
["<p>[foo<p>bar]",
[["formatblock","<ul>"]],
"<p>[foo</p><p>bar]</p>",
@@ -1672,44 +1750,44 @@ var browserTests = [
{"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[true,false,"",false,false,"h1"]}],
["<div>[foo<p>bar]</p></div>",
[["defaultparagraphseparator","div"],["formatblock","<p>"]],
- "<div><p>[foo</p><p>bar]</p></div>",
+ "<p>[foo</p><div><p>bar]</p></div>",
[true,true],
{"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[true,false,"",false,false,"p"]}],
["<div>[foo<p>bar]</p></div>",
[["defaultparagraphseparator","p"],["formatblock","<p>"]],
- "<div><p>[foo</p><p>bar]</p></div>",
+ "<p>[foo</p><div><p>bar]</p></div>",
[true,true],
{"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[true,false,"",false,false,"p"]}],
["<xmp>[foo]</xmp>",
[["defaultparagraphseparator","div"],["formatblock","<p>"]],
- "<p>[foo]</p>",
+ "<p><xmp>[foo]</xmp></p>",
[true,true],
{"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"p"]}],
["<xmp>[foo]</xmp>",
[["defaultparagraphseparator","p"],["formatblock","<p>"]],
- "<p>[foo]</p>",
+ "<p><xmp>[foo]</xmp></p>",
[true,true],
{"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"p"]}],
["<xmp>[foo]</xmp>",
[["defaultparagraphseparator","div"],["formatblock","<div>"]],
- "<div>[foo]</div>",
+ "<div><xmp>[foo]</xmp></div>",
[true,true],
{"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"div"]}],
["<xmp>[foo]</xmp>",
[["defaultparagraphseparator","p"],["formatblock","<div>"]],
- "<div>[foo]</div>",
+ "<div><xmp>[foo]</xmp></div>",
[true,true],
{"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"div"]}],
["<div><ol><li>[foo]</ol></div>",
[["defaultparagraphseparator","div"],["formatblock","<div>"]],
- "<div><ol><li><div>[foo]</div></li></ol></div>",
+ "<div><ol><li>[foo]</li></ol></div>",
[true,true],
- {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"",false,false,"div"]}],
+ {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"div",false,false,"div"]}],
["<div><ol><li>[foo]</ol></div>",
[["defaultparagraphseparator","p"],["formatblock","<div>"]],
- "<div><ol><li><div>[foo]</div></li></ol></div>",
+ "<div><ol><li>[foo]</li></ol></div>",
[true,true],
- {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"",false,false,"div"]}],
+ {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"div",false,false,"div"]}],
["<div><table><tr><td>[foo]</table></div>",
[["defaultparagraphseparator","div"],["formatblock","<div>"]],
"<div><table><tbody><tr><td><div>[foo]</div></td></tr></tbody></table></div>",
@@ -1752,22 +1830,22 @@ var browserTests = [
{"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[true,false,"div",false,false,"div"]}],
["<div style=color:blue>[foo]</div>",
[["stylewithcss","true"],["defaultparagraphseparator","div"],["formatblock","<p>"]],
- "<p><span style=\"color:rgb(0, 0, 255)\">[foo]</span></p>",
+ "<p style=\"color:rgb(0, 0, 255)\">[foo]</p>",
[true,true,true],
{"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"div",false,false,"p"]}],
["<div style=color:blue>[foo]</div>",
[["stylewithcss","false"],["defaultparagraphseparator","div"],["formatblock","<p>"]],
- "<p><font color=\"#0000ff\">[foo]</font></p>",
+ "<p style=\"color:rgb(0, 0, 255)\">[foo]</p>",
[true,true,true],
{"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"div",false,false,"div"],"formatblock":[false,false,"div",false,false,"p"]}],
["<div style=color:blue>[foo]</div>",
[["stylewithcss","true"],["defaultparagraphseparator","p"],["formatblock","<p>"]],
- "<p><span style=\"color:rgb(0, 0, 255)\">[foo]</span></p>",
+ "<p style=\"color:rgb(0, 0, 255)\">[foo]</p>",
[true,true,true],
{"stylewithcss":[false,false,"",false,true,""],"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"div",false,false,"p"]}],
["<div style=color:blue>[foo]</div>",
[["stylewithcss","false"],["defaultparagraphseparator","p"],["formatblock","<p>"]],
- "<p><font color=\"#0000ff\">[foo]</font></p>",
+ "<p style=\"color:rgb(0, 0, 255)\">[foo]</p>",
[true,true,true],
{"stylewithcss":[false,true,"",false,false,""],"defaultparagraphseparator":[false,false,"p",false,false,"p"],"formatblock":[false,false,"div",false,false,"p"]}],
["{<p>foo</p>ba]r",
diff --git a/tests/wpt/tests/editing/edit-context/edit-context-input.tentative.html b/tests/wpt/tests/editing/edit-context/edit-context-input.tentative.html
index 0f05606a356..f65dfbc915d 100644
--- a/tests/wpt/tests/editing/edit-context/edit-context-input.tentative.html
+++ b/tests/wpt/tests/editing/edit-context/edit-context-input.tentative.html
@@ -31,8 +31,6 @@
document.body.appendChild(test);
test.editContext = editContext;
test.focus();
- textInputController.setComposition("foo");
- assert_equals(test.innerHTML, "");
await test_driver.send_keys(test, 'a');
assert_equals(test.innerHTML, "");
test.remove();
diff --git a/tests/wpt/tests/fetch/fetch-later/headers/header-referrer-no-referrer-when-downgrade.tentative.https.html b/tests/wpt/tests/fetch/fetch-later/headers/header-referrer-no-referrer-when-downgrade.tentative.https.html
new file mode 100644
index 00000000000..38eada4513c
--- /dev/null
+++ b/tests/wpt/tests/fetch/fetch-later/headers/header-referrer-no-referrer-when-downgrade.tentative.https.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<html>
+<head>
+<title>FetchLater Referrer Header: No Referrer When Downgrade Policy</title>
+<meta name='referrer' content='no-referrer-when-downgrade'>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/utils.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="/fetch/fetch-later/resources/header-referrer-helper.js"></script>
+</head>
+<body>
+<script>
+
+const {
+ HTTPS_ORIGIN,
+} = get_host_info();
+
+testReferrerHeader(token(), HTTPS_ORIGIN, REFERRER_URL);
+
+</script>
+</body>
+</html>
diff --git a/tests/wpt/tests/fetch/fetch-later/headers/header-referrer-no-referrer.tentative.https.html b/tests/wpt/tests/fetch/fetch-later/headers/header-referrer-no-referrer.tentative.https.html
new file mode 100644
index 00000000000..75e9ece7ba5
--- /dev/null
+++ b/tests/wpt/tests/fetch/fetch-later/headers/header-referrer-no-referrer.tentative.https.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<html>
+<head>
+<title>FetchLater Referrer Header: No Referrer Policy</title>
+<meta name='referrer' content='no-referrer'>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/utils.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="/fetch/fetch-later/resources/header-referrer-helper.js"></script>
+</head>
+<body>
+<script>
+
+testReferrerHeader(token(), /*host=*/'', /*expectedReferer=*/"");
+
+</script>
+</body>
+</html>
diff --git a/tests/wpt/tests/fetch/fetch-later/headers/header-referrer-origin-when-cross-origin.tentative.https.html b/tests/wpt/tests/fetch/fetch-later/headers/header-referrer-origin-when-cross-origin.tentative.https.html
new file mode 100644
index 00000000000..b9f14171ba3
--- /dev/null
+++ b/tests/wpt/tests/fetch/fetch-later/headers/header-referrer-origin-when-cross-origin.tentative.https.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<html>
+<head>
+<title>FetchLater Referrer Header: Origin When Cross Origin Policy</title>
+<meta name='referrer' content='origin-when-cross-origin'>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/utils.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="/fetch/fetch-later/resources/header-referrer-helper.js"></script>
+</head>
+<body>
+<script>
+
+const {
+ HTTPS_ORIGIN,
+ HTTPS_REMOTE_ORIGIN
+} = get_host_info();
+
+testReferrerHeader(token(), HTTPS_ORIGIN, REFERRER_URL);
+testReferrerHeader(token(), HTTPS_REMOTE_ORIGIN, REFERRER_ORIGIN);
+
+</script>
+</body>
+</html>
diff --git a/tests/wpt/tests/fetch/fetch-later/headers/header-referrer-origin.tentative.https.html b/tests/wpt/tests/fetch/fetch-later/headers/header-referrer-origin.tentative.https.html
new file mode 100644
index 00000000000..ce7abf92039
--- /dev/null
+++ b/tests/wpt/tests/fetch/fetch-later/headers/header-referrer-origin.tentative.https.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<html>
+<head>
+<title>FetchLater Referrer Header: Origin Policy</title>
+<meta name='referrer' content='origin'>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/utils.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="/fetch/fetch-later/resources/header-referrer-helper.js"></script>
+</head>
+<body>
+<script>
+
+const {
+ HTTPS_REMOTE_ORIGIN
+} = get_host_info();
+
+testReferrerHeader(token(), HTTPS_REMOTE_ORIGIN, REFERRER_ORIGIN);
+
+</script>
+</body>
+</html>
diff --git a/tests/wpt/tests/fetch/fetch-later/headers/header-referrer-same-origin.tentative.https.html b/tests/wpt/tests/fetch/fetch-later/headers/header-referrer-same-origin.tentative.https.html
new file mode 100644
index 00000000000..264beddc03a
--- /dev/null
+++ b/tests/wpt/tests/fetch/fetch-later/headers/header-referrer-same-origin.tentative.https.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<html>
+<head>
+<title>FetchLater Referrer Header: Same Origin Policy</title>
+<meta name='referrer' content='same-origin'>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/utils.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="/fetch/fetch-later/resources/header-referrer-helper.js"></script>
+</head>
+<body>
+<script>
+
+const {
+ HTTPS_REMOTE_ORIGIN
+} = get_host_info();
+
+testReferrerHeader(token(), /*host=*/'', REFERRER_URL);
+testReferrerHeader(token(), HTTPS_REMOTE_ORIGIN, /*expectedReferrer=*/'');
+
+</script>
+</body>
+</html>
diff --git a/tests/wpt/tests/fetch/fetch-later/headers/header-referrer-strict-origin-when-cross-origin.tentative.https.html b/tests/wpt/tests/fetch/fetch-later/headers/header-referrer-strict-origin-when-cross-origin.tentative.https.html
new file mode 100644
index 00000000000..9133f2496fe
--- /dev/null
+++ b/tests/wpt/tests/fetch/fetch-later/headers/header-referrer-strict-origin-when-cross-origin.tentative.https.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<html>
+<head>
+<title>FetchLater Referrer Header: Strict Origin Policy</title>
+<meta name='referrer' content='strict-origin'>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/utils.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="/fetch/fetch-later/resources/header-referrer-helper.js"></script>
+</head>
+<body>
+<script>
+
+const {
+ HTTPS_REMOTE_ORIGIN
+} = get_host_info();
+
+testReferrerHeader(token(), HTTPS_REMOTE_ORIGIN, REFERRER_ORIGIN);
+// Note: FetchLater cannot be used for non-secure URL.
+
+</script>
+</body>
+</html>
diff --git a/tests/wpt/tests/fetch/fetch-later/headers/header-referrer-strict-origin.tentative.https.html b/tests/wpt/tests/fetch/fetch-later/headers/header-referrer-strict-origin.tentative.https.html
new file mode 100644
index 00000000000..943d70bbc58
--- /dev/null
+++ b/tests/wpt/tests/fetch/fetch-later/headers/header-referrer-strict-origin.tentative.https.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<html>
+<head>
+<title>FetchLater Referrer Header: Strict Origin Policy</title>
+<meta name='referrer' content='strict-origin'>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/utils.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="/fetch/fetch-later/resources/header-referrer-helper.js"></script>
+</head>
+<body>
+<script>
+
+const {
+ HTTPS_ORIGIN
+} = get_host_info();
+
+testReferrerHeader(token(), HTTPS_ORIGIN, REFERRER_ORIGIN);
+// Note: FetchLater cannot be used for non-secure URL.
+
+</script>
+</body>
+</html>
diff --git a/tests/wpt/tests/fetch/fetch-later/headers/header-referrer-unsafe-url.tentative.https.html b/tests/wpt/tests/fetch/fetch-later/headers/header-referrer-unsafe-url.tentative.https.html
new file mode 100644
index 00000000000..a602e0003a4
--- /dev/null
+++ b/tests/wpt/tests/fetch/fetch-later/headers/header-referrer-unsafe-url.tentative.https.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<html>
+<head>
+<title>FetchLater Referrer Header: Unsafe Url Policy</title>
+<meta name='referrer' content='unsafe-url'>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/utils.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="/fetch/fetch-later/resources/header-referrer-helper.js"></script>
+</head>
+<body>
+<script>
+
+const {
+ HTTPS_ORIGIN
+} = get_host_info();
+
+testReferrerHeader(token(), HTTPS_ORIGIN, REFERRER_URL);
+// Note: FetchLater cannot be used for non-secure URL.
+
+</script>
+</body>
+</html>
diff --git a/tests/wpt/tests/fetch/fetch-later/iframe.tentative.https.window.js b/tests/wpt/tests/fetch/fetch-later/iframe.tentative.https.window.js
new file mode 100644
index 00000000000..62505bc81d9
--- /dev/null
+++ b/tests/wpt/tests/fetch/fetch-later/iframe.tentative.https.window.js
@@ -0,0 +1,65 @@
+// META: script=/resources/testharness.js
+// META: script=/resources/testharnessreport.js
+// META: script=/common/utils.js
+// META: script=/common/get-host-info.sub.js
+// META: script=/pending-beacon/resources/pending_beacon-helper.js
+
+'use strict';
+
+const {
+ HTTPS_ORIGIN,
+ HTTPS_NOTSAMESITE_ORIGIN,
+} = get_host_info();
+
+async function loadElement(el) {
+ const loaded = new Promise(resolve => el.onload = resolve);
+ document.body.appendChild(el);
+ await loaded;
+}
+
+// `host` may be cross-origin
+async function loadFetchLaterIframe(host, targetUrl) {
+ const url = `${host}/fetch/fetch-later/resources/fetch-later.html?url=${
+ encodeURIComponent(targetUrl)}`;
+ const iframe = document.createElement('iframe');
+ iframe.src = url;
+ await loadElement(iframe);
+ return iframe;
+}
+
+parallelPromiseTest(async t => {
+ const uuid = token();
+ const url = generateSetBeaconURL(uuid);
+
+ // Loads a blank iframe that fires a fetchLater request.
+ const iframe = document.createElement('iframe');
+ iframe.addEventListener('load', () => {
+ fetchLater(url, {activateAfter: 0});
+ });
+ await loadElement(iframe);
+
+ // The iframe should have sent the request.
+ await expectBeacon(uuid, {count: 1});
+}, 'A blank iframe can trigger fetchLater.');
+
+parallelPromiseTest(async t => {
+ const uuid = token();
+ const url = generateSetBeaconURL(uuid);
+
+ // Loads a same-origin iframe that fires a fetchLater request.
+ await loadFetchLaterIframe(HTTPS_ORIGIN, url);
+
+ // The iframe should have sent the request.
+ await expectBeacon(uuid, {count: 1});
+}, 'A same-origin iframe can trigger fetchLater.');
+
+parallelPromiseTest(async t => {
+ const uuid = token();
+ const url = generateSetBeaconURL(uuid);
+
+ // Loads a same-origin iframe that fires a fetchLater request.
+ await loadFetchLaterIframe(HTTPS_NOTSAMESITE_ORIGIN, url);
+
+ // The iframe should have sent the request.
+ await expectBeacon(uuid, {count: 1});
+}, 'A cross-origin iframe can trigger fetchLater.');
diff --git a/tests/wpt/tests/fetch/fetch-later/new-window.tentative.https.window.js b/tests/wpt/tests/fetch/fetch-later/new-window.tentative.https.window.js
new file mode 100644
index 00000000000..37b38d7f1dc
--- /dev/null
+++ b/tests/wpt/tests/fetch/fetch-later/new-window.tentative.https.window.js
@@ -0,0 +1,77 @@
+// META: script=/resources/testharness.js
+// META: script=/resources/testharnessreport.js
+// META: script=/common/utils.js
+// META: script=/common/get-host-info.sub.js
+// META: script=/pending-beacon/resources/pending_beacon-helper.js
+
+'use strict';
+
+const {
+ HTTPS_ORIGIN,
+ HTTPS_NOTSAMESITE_ORIGIN,
+} = get_host_info();
+
+function fetchLaterPopupUrl(host, targetUrl) {
+ return `${host}/fetch/fetch-later/resources/fetch-later.html?url=${
+ encodeURIComponent(targetUrl)}`;
+}
+
+for (const target of ['', '_blank']) {
+ for (const features in ['', 'popup', 'popup,noopener']) {
+ parallelPromiseTest(
+ async t => {
+ const uuid = token();
+ const url =
+ generateSetBeaconURL(uuid, {host: HTTPS_NOTSAMESITE_ORIGIN});
+
+ // Opens a blank popup window that fires a fetchLater request.
+ const w = window.open(
+ `javascript: fetchLater("${url}", {activateAfter: 0})`, target,
+ features);
+ await new Promise(resolve => w.addEventListener('load', resolve));
+
+ // The popup should have sent the request.
+ await expectBeacon(uuid, {count: 1});
+ w.close();
+ },
+ `A blank window[target='${target}'][features='${
+ features}'] can trigger fetchLater.`);
+
+ parallelPromiseTest(
+ async t => {
+ const uuid = token();
+ const popupUrl =
+ fetchLaterPopupUrl(HTTPS_ORIGIN, generateSetBeaconURL(uuid));
+
+ // Opens a same-origin popup that fires a fetchLater request.
+ const w = window.open(popupUrl, target, features);
+ await new Promise(resolve => w.addEventListener('load', resolve));
+
+ // The popup should have sent the request.
+ await expectBeacon(uuid, {count: 1});
+ w.close();
+ },
+ `A same-origin window[target='${target}'][features='${
+ features}'] can trigger fetchLater.`);
+
+ parallelPromiseTest(
+ async t => {
+ const uuid = token();
+ const popupUrl = fetchLaterPopupUrl(
+ HTTPS_NOTSAMESITE_ORIGIN, generateSetBeaconURL(uuid));
+
+ // Opens a cross-origin popup that fires a fetchLater request.
+ const w = window.open(popupUrl, target, features);
+ // As events from cross-origin window is not accessible, waiting for
+ // its message instead.
+ await new Promise(
+ resolve => window.addEventListener('message', resolve));
+
+ // The popup should have sent the request.
+ await expectBeacon(uuid, {count: 1});
+ w.close();
+ },
+ `A cross-origin window[target='${target}'][features='${
+ features}'] can trigger fetchLater.`);
+ }
+}
diff --git a/tests/wpt/tests/fetch/fetch-later/policies/csp-allowed.tentative.https.window.js b/tests/wpt/tests/fetch/fetch-later/policies/csp-allowed.tentative.https.window.js
new file mode 100644
index 00000000000..5aa759c2346
--- /dev/null
+++ b/tests/wpt/tests/fetch/fetch-later/policies/csp-allowed.tentative.https.window.js
@@ -0,0 +1,28 @@
+// META: title=FetchLater: allowed by CSP
+// META: script=/resources/testharness.js
+// META: script=/resources/testharnessreport.js
+// META: script=/common/utils.js
+// META: script=/common/get-host-info.sub.js
+// META: script=/pending-beacon/resources/pending_beacon-helper.js
+'use strict';
+
+const {
+ HTTPS_NOTSAMESITE_ORIGIN,
+} = get_host_info();
+
+// FetchLater requests allowed by Content Security Policy.
+// https://w3c.github.io/webappsec-csp/#should-block-request
+
+const meta = document.createElement('meta');
+meta.setAttribute('http-equiv', 'Content-Security-Policy');
+meta.setAttribute('content', `connect-src 'self' ${HTTPS_NOTSAMESITE_ORIGIN}`);
+document.head.appendChild(meta);
+
+promise_test(async t => {
+ const uuid = token();
+ const url = generateSetBeaconURL(uuid, {host: HTTPS_NOTSAMESITE_ORIGIN});
+ fetchLater(url, {activateAfter: 0});
+
+ await expectBeacon(uuid, {count: 1});
+ t.done();
+}, 'FetchLater allowed by CSP should succeed');
diff --git a/tests/wpt/tests/fetch/fetch-later/policies/csp-blocked.tentative.https.window.js b/tests/wpt/tests/fetch/fetch-later/policies/csp-blocked.tentative.https.window.js
new file mode 100644
index 00000000000..88490950d3a
--- /dev/null
+++ b/tests/wpt/tests/fetch/fetch-later/policies/csp-blocked.tentative.https.window.js
@@ -0,0 +1,33 @@
+// META: title=FetchLater: blocked by CSP
+// META: script=/resources/testharness.js
+// META: script=/resources/testharnessreport.js
+// META: script=/common/utils.js
+// META: script=/common/get-host-info.sub.js
+// META: script=/pending-beacon/resources/pending_beacon-helper.js
+'use strict';
+
+const {
+ HTTPS_NOTSAMESITE_ORIGIN,
+} = get_host_info();
+
+// FetchLater requests blocked by Content Security Policy are rejected.
+// https://w3c.github.io/webappsec-csp/#should-block-request
+
+const meta = document.createElement('meta');
+meta.setAttribute('http-equiv', 'Content-Security-Policy');
+meta.setAttribute('content', 'connect-src \'self\'');
+document.head.appendChild(meta);
+
+promise_test(async t => {
+ const uuid = token();
+ const cspViolationUrl =
+ generateSetBeaconURL(uuid, {host: HTTPS_NOTSAMESITE_ORIGIN});
+ fetchLater(cspViolationUrl, {activateAfter: 0});
+
+ await new Promise(
+ resolve => window.addEventListener('securitypolicyviolation', e => {
+ assert_equals(e.violatedDirective, 'connect-src');
+ resolve();
+ }));
+ t.done();
+}, 'FetchLater blocked by CSP should reject');
diff --git a/tests/wpt/tests/fetch/fetch-later/policies/csp-redirect-to-blocked.tentative.https.window.js b/tests/wpt/tests/fetch/fetch-later/policies/csp-redirect-to-blocked.tentative.https.window.js
new file mode 100644
index 00000000000..c2019881cc2
--- /dev/null
+++ b/tests/wpt/tests/fetch/fetch-later/policies/csp-redirect-to-blocked.tentative.https.window.js
@@ -0,0 +1,33 @@
+// META: title=FetchLater: redirect blocked by CSP
+// META: script=/resources/testharness.js
+// META: script=/resources/testharnessreport.js
+// META: script=/common/utils.js
+// META: script=/common/get-host-info.sub.js
+// META: script=/pending-beacon/resources/pending_beacon-helper.js
+'use strict';
+
+const {
+ HTTPS_NOTSAMESITE_ORIGIN,
+} = get_host_info();
+
+// FetchLater requests redirect to URL blocked by Content Security Policy.
+// https://w3c.github.io/webappsec-csp/#should-block-request
+
+const meta = document.createElement('meta');
+meta.setAttribute('http-equiv', 'Content-Security-Policy');
+meta.setAttribute('content', 'connect-src \'self\'');
+document.head.appendChild(meta);
+
+promise_test(async t => {
+ const uuid = token();
+ const cspViolationUrl =
+ generateSetBeaconURL(uuid, {host: HTTPS_NOTSAMESITE_ORIGIN});
+ const url =
+ `/common/redirect.py?location=${encodeURIComponent(cspViolationUrl)}`;
+ fetchLater(url, {activateAfter: 0});
+
+ // TODO(crbug.com/1465781): redirect csp check is handled in browser, of which
+ // result cannot be populated to renderer at this moment.
+ await expectBeacon(uuid, {count: 0});
+ t.done();
+}, 'FetchLater redirect blocked by CSP should reject');
diff --git a/tests/wpt/tests/fetch/fetch-later/resources/fetch-later.html b/tests/wpt/tests/fetch/fetch-later/resources/fetch-later.html
new file mode 100644
index 00000000000..b569e1a076a
--- /dev/null
+++ b/tests/wpt/tests/fetch/fetch-later/resources/fetch-later.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<head>
+</head>
+<body>
+ <script>
+ const PARAMS = new URL(location.href).searchParams;
+ const TARGET_URL= decodeURIComponent(PARAMS.get('url')) || '';
+
+ fetchLater(TARGET_URL, {activateAfter: 0});
+ if (window.opener) {
+ window.opener.postMessage("done", "*");
+ }
+ </script>
+</body>
diff --git a/tests/wpt/tests/fetch/fetch-later/resources/header-referrer-helper.js b/tests/wpt/tests/fetch/fetch-later/resources/header-referrer-helper.js
new file mode 100644
index 00000000000..374097614ae
--- /dev/null
+++ b/tests/wpt/tests/fetch/fetch-later/resources/header-referrer-helper.js
@@ -0,0 +1,39 @@
+'use strict';
+
+// https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer
+const REFERRER_ORIGIN = self.location.origin + '/';
+const REFERRER_URL = self.location.href;
+
+function testReferrerHeader(id, host, expectedReferrer) {
+ const url = `${
+ host}/beacon/resources/inspect-header.py?header=referer&cmd=put&id=${id}`;
+
+ promise_test(t => {
+ fetchLater(url, {activateAfter: 0});
+ return pollResult(expectedReferrer, id).then(result => {
+ assert_equals(result, expectedReferrer, 'Correct referrer header result');
+ });
+ }, `Test referer header ${host}`);
+}
+
+function pollResult(expectedReferrer, id) {
+ const checkUrl =
+ `/beacon/resources/inspect-header.py?header=referer&cmd=get&id=${id}`;
+
+ return new Promise(resolve => {
+ function checkResult() {
+ fetch(checkUrl).then(response => {
+ assert_equals(
+ response.status, 200, 'Inspect header response\'s status is 200');
+ let result = response.headers.get('x-request-referer');
+
+ if (result != undefined) {
+ resolve(result);
+ } else {
+ step_timeout(checkResult.bind(this), 100);
+ }
+ });
+ }
+ checkResult();
+ });
+}
diff --git a/tests/wpt/tests/fetch/fetch-later/send-on-deactivate.tentative.https.window.js b/tests/wpt/tests/fetch/fetch-later/send-on-deactivate.tentative.https.window.js
index 7a1ddc7ac3d..173c95ac120 100644
--- a/tests/wpt/tests/fetch/fetch-later/send-on-deactivate.tentative.https.window.js
+++ b/tests/wpt/tests/fetch/fetch-later/send-on-deactivate.tentative.https.window.js
@@ -101,3 +101,36 @@ parallelPromiseTest(async t => {
await expectBeacon(uuid, {count: 1});
}, `fetchLater() sends on navigating away a page w/o BFCache.`);
+
+parallelPromiseTest(async t => {
+ const uuid = token();
+ const url = generateSetBeaconURL(uuid);
+ // Sets no option to test the default behavior when a document gets discarded
+ // on navigated away.
+ const helper = new RemoteContextHelper();
+ // Opens a window without BFCache.
+ const rc1 = await helper.addWindow();
+
+ // Creates 2 fetchLater requests in remote, and one of them is aborted
+ // immediately. The other one should only be sent right on navigating away.
+ await rc1.executeScript(url => {
+ const controller = new AbortController();
+ fetchLater(url, {signal: controller.signal});
+ fetchLater(url);
+ controller.abort();
+ // Add a pageshow listener to stash the BFCache event.
+ window.addEventListener('pageshow', e => {
+ window.pageshowEvent = e;
+ });
+ }, [url]);
+ // Navigates away to trigger request sending.
+ const rc2 = await rc1.navigateToNew();
+ // Navigate back.
+ await rc2.historyBack();
+ // Verify that the page was NOT BFCached.
+ assert_equals(undefined, await rc1.executeScript(() => {
+ return window.pageshowEvent;
+ }));
+
+ await expectBeacon(uuid, {count: 1});
+}, `fetchLater() does not send aborted request on navigating away a page w/o BFCache.`);
diff --git a/tests/wpt/tests/fetch/fetch-later/send-on-discard.tentative.https.window.js b/tests/wpt/tests/fetch/fetch-later/send-on-discard.tentative.https.window.js
index c4911b11055..e1ff9b9e3a6 100644
--- a/tests/wpt/tests/fetch/fetch-later/send-on-discard.tentative.https.window.js
+++ b/tests/wpt/tests/fetch/fetch-later/send-on-discard.tentative.https.window.js
@@ -63,6 +63,5 @@ parallelPromiseTest(async t => {
document.body.removeChild(iframe);
// The iframe should not send the aborted request.
- // TODO(crbug.com/1465781): Fix this after implementing abort function.
await expectBeacon(uuid, {count: 1});
}, 'A discarded document does not send an already aborted fetchLater request.');
diff --git a/tests/wpt/tests/fledge/tentative/TODO b/tests/wpt/tests/fledge/tentative/TODO
index 2b6a1dc3c2d..272a5e3ffb9 100644
--- a/tests/wpt/tests/fledge/tentative/TODO
+++ b/tests/wpt/tests/fledge/tentative/TODO
@@ -12,12 +12,11 @@ Need tests for (likely not a complete list):
probably not worth covering all types, if we have coverage for the
main renderURL).
* Filtering/prioritization (including bidding signals influencing priorities)
-* Size restrictions.
+* Size restrictions / ad and component ad sizes.
* additionalBids.
* adCost.
* bidCurrency.
* modellingSignals.
-* Ad and component ad sizes.
* Updates (both after auction and triggered).
* All auctionConfig parameters (including invalid auctionConfigs, and ones
with no buyers).
@@ -40,9 +39,8 @@ Need tests for (likely not a complete list):
* Network timeouts.
* Validate specific escaping behavior logic (still under discussion). There
are a number of different rules for which characters are escaped, and
- whether spacess are escaped as "%20" or "+".
+ whether spaces are escaped as "%20" or "+".
* Reports not sent if ad not used.
-* Ties.
* Interactions with local network access API, which requires public
networks to send CORS preflights for requests made over local networks.
Needs testing with public publisher pages running auctions with
@@ -50,10 +48,8 @@ Need tests for (likely not a complete list):
* Calling FLEDGE APIs (or at least leaveAdInterestGroup() with no args)
in a non-ad FencedFrame.
* Test network requests in terms of fetch behavior
- * No cookies.
- * No referrer.
* Redirects not followed.
- * etc.
+ * Network partition (not yet specced).
* Test that await is not needed for same-origin interest groups
* Verify that's still in the spec/explainer first.
* executionMode
@@ -62,12 +58,13 @@ Need tests for (likely not a complete list):
* Across scoreAd() / generateBid() calls, and with report calls.
* In "group-by-origin" execution mode across IGs joined from different
origins, and between generateBid() and reportWin().
-* Use AbortSignal to abort an auction.
+* Test Content-Type headers allowed in responess for script/wasm/JSON fetches.
If possible:
* Aggregate reporting.
* Join/leave permission delegation via .well-known files
* Including tests for clearOriginJoinedInterestGroups().
+ * Include tests for HTTP-y/fetch-y things (e.g., whether they have cookies)
* k-anonymity.
* Signals request batching. This is an optional feature, so can't require it,
but maybe a test where batching could be used, and make sure things work,
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 e4811b96965..432be9cb10a 100644
--- a/tests/wpt/tests/fledge/tentative/auction-config.https.window.js
+++ b/tests/wpt/tests/fledge/tentative/auction-config.https.window.js
@@ -7,7 +7,8 @@
// META: variant=?6-10
// META: variant=?11-15
// META: variant=?16-20
-// META: variant=?21-last
+// META: variant=?21-25
+// META: variant=?26-last
"use strict;"
@@ -276,3 +277,31 @@ makeTest({
],
},
});
+
+makeTest({
+ name: 'perBuyerCurrencies with invalid currency',
+ expect: EXPECT_PROMISE_ERROR,
+ expectPromiseError: EXPECT_EXCEPTION(TypeError),
+ auctionConfigOverrides: {perBuyerCurrencies: {'*': 'Dollars'}}
+});
+
+makeTest({
+ name: 'perBuyerCurrencies with invalid currency map key',
+ expect: EXPECT_PROMISE_ERROR,
+ expectPromiseError: EXPECT_EXCEPTION(TypeError),
+ auctionConfigOverrides: {perBuyerCurrencies: {'example': 'USD'}}
+});
+
+makeTest({
+ name: 'perBuyerCurrencies with non-https currency map key',
+ expect: EXPECT_PROMISE_ERROR,
+ expectPromiseError: EXPECT_EXCEPTION(TypeError),
+ auctionConfigOverrides: {perBuyerCurrencies: {'http://example.org/': 'USD'}}
+});
+
+makeTest({
+ name: 'perBuyerCurrencies not convertible to dictionary',
+ expect: EXPECT_PROMISE_ERROR,
+ expectPromiseError: EXPECT_EXCEPTION(TypeError),
+ auctionConfigOverrides: {perBuyerCurrencies: 123}
+});
diff --git a/tests/wpt/tests/fledge/tentative/currency.https.window.js b/tests/wpt/tests/fledge/tentative/currency.https.window.js
new file mode 100644
index 00000000000..97802ce1379
--- /dev/null
+++ b/tests/wpt/tests/fledge/tentative/currency.https.window.js
@@ -0,0 +1,124 @@
+// 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-4
+// META: variant=?5-last
+
+'use strict;'
+
+// The tests in this file focus on calls to runAdAuction involving currency
+// handling.
+
+// Joins an interest group that bids 9USD on window.location.origin, and one
+// that bids 10CAD on OTHER_ORIGIN1, each with a reportWin() report.
+async function joinTwoCurrencyGroups(test, uuid) {
+ const reportWinURL = createBidderReportURL(uuid, 'USD');
+ const biddingURL = createBiddingScriptURL(
+ {bidCurrency: 'USD', reportWin: `sendReportTo('${reportWinURL}')`});
+ await joinInterestGroup(test, uuid, {biddingLogicURL: biddingURL});
+
+ const otherReportWinURL = createBidderReportURL(uuid, 'CAD', OTHER_ORIGIN1);
+ const otherBiddingURL = createBiddingScriptURL({
+ origin: OTHER_ORIGIN1,
+ bid: 10,
+ bidCurrency: 'CAD',
+ reportWin: `sendReportTo('${otherReportWinURL}')`
+ });
+ await joinCrossOriginInterestGroup(
+ test, uuid, OTHER_ORIGIN1, {biddingLogicURL: otherBiddingURL});
+}
+
+subsetTest(promise_test, async test => {
+ const uuid = generateUuid(test);
+ await joinInterestGroup(
+ test, uuid,
+ {biddingLogicURL: createBiddingScriptURL({bidCurrency: 'usd'})});
+ await runBasicFledgeTestExpectingNoWinner(test, uuid);
+}, 'Returning bid with invalid currency.');
+
+subsetTest(promise_test, async test => {
+ const uuid = generateUuid(test);
+ await joinInterestGroup(
+ test, uuid,
+ {biddingLogicURL: createBiddingScriptURL({bidCurrency: 'USD'})});
+ await runBasicFledgeTestExpectingWinner(test, uuid);
+}, 'Returning bid with currency, configuration w/o currency.');
+
+subsetTest(promise_test, async test => {
+ const uuid = generateUuid(test);
+ await joinInterestGroup(test, uuid);
+ await runBasicFledgeTestExpectingWinner(
+ test, uuid, {perBuyerCurrencies: {'*': 'USD'}});
+}, 'Returning bid w/o currency, configuration w/currency.');
+
+subsetTest(promise_test, async test => {
+ const uuid = generateUuid(test);
+ await joinInterestGroup(
+ test, uuid,
+ {biddingLogicURL: createBiddingScriptURL({bidCurrency: 'USD'})});
+ await runBasicFledgeTestExpectingWinner(
+ test, uuid, {perBuyerCurrencies: {'*': 'USD'}});
+}, 'Returning bid w/currency, configuration w/matching currency.');
+
+subsetTest(promise_test, async test => {
+ const uuid = generateUuid(test);
+ await joinInterestGroup(
+ test, uuid,
+ {biddingLogicURL: createBiddingScriptURL({bidCurrency: 'USD'})});
+ await runBasicFledgeTestExpectingNoWinner(
+ test, uuid, {perBuyerCurrencies: {'*': 'CAD'}});
+}, 'Returning bid w/currency, configuration w/different currency.');
+
+subsetTest(promise_test, async test => {
+ const uuid = generateUuid(test);
+ await joinTwoCurrencyGroups(test, uuid);
+ let auctionConfigOverrides = {
+ interestGroupBuyers: [window.location.origin, OTHER_ORIGIN1],
+ perBuyerCurrencies: {}
+ };
+ auctionConfigOverrides.perBuyerCurrencies['*'] = 'USD';
+ auctionConfigOverrides.perBuyerCurrencies[OTHER_ORIGIN1] = 'CAD';
+ await runBasicFledgeAuctionAndNavigate(test, uuid, auctionConfigOverrides);
+
+ // Since the scoring script doesn't actually look at the currencies,
+ // We expect 10CAD to win because 10 > 9
+ await waitForObservedRequests(uuid, [
+ createBidderReportURL(uuid, 'CAD', OTHER_ORIGIN1),
+ createSellerReportURL(uuid)
+ ]);
+}, 'Different currencies for different origins, all match.');
+
+subsetTest(promise_test, async test => {
+ const uuid = generateUuid(test);
+ await joinTwoCurrencyGroups(test, uuid);
+ let auctionConfigOverrides = {
+ interestGroupBuyers: [window.location.origin, OTHER_ORIGIN1],
+ perBuyerCurrencies: {}
+ };
+ auctionConfigOverrides.perBuyerCurrencies[window.location.origin] = 'USD';
+ auctionConfigOverrides.perBuyerCurrencies[OTHER_ORIGIN1] = 'EUR';
+ await runBasicFledgeAuctionAndNavigate(test, uuid, auctionConfigOverrides);
+
+ // Since the configuration for CAD script expects EUR only the USD bid goes
+ // through.
+ await waitForObservedRequests(
+ uuid, [createBidderReportURL(uuid, 'USD'), createSellerReportURL(uuid)]);
+}, 'Different currencies for different origins, USD one matches.');
+
+subsetTest(promise_test, async test => {
+ const uuid = generateUuid(test);
+ await joinTwoCurrencyGroups(test, uuid);
+ let auctionConfigOverrides = {
+ interestGroupBuyers: [window.location.origin, OTHER_ORIGIN1],
+ perBuyerCurrencies: {}
+ };
+ auctionConfigOverrides.perBuyerCurrencies['*'] = 'EUR';
+}, 'Different currencies for different origins, none match.');
+
+// TODO: look at currency passed in to scoring.
+// Conversion to uniform currency (integrate private aggregation to check)
+// --- also the passthrough and can't modify rule for things already in it.
+// Basic sellerCurrency checks (requires component auctions; can be
+// pass-through or modified bid).
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 77da23a7a5b..107bd3b815a 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
@@ -637,14 +637,3 @@ subsetTest(promise_test, async test => {
await joinInterestGroup(test, uuid, {}, -600);
assert_true(await runBasicFledgeAuction(test, uuid) === null);
}, 'Interest group test with overwritten duration of -600.');
-
-subsetTest(promise_test, async test => {
- try {
- await navigator.leaveAdInterestGroup();
- } catch (e) {
- assert_true(e instanceof TypeError, 'TypeError thrown');
- return;
- }
-
- throw 'TypeError unexpectedly not thrown.'
-}, 'leaveInterestGroup() with no parameters, outside of a fenced frame.');
diff --git a/tests/wpt/tests/fledge/tentative/network.https.window.js b/tests/wpt/tests/fledge/tentative/network.https.window.js
new file mode 100644
index 00000000000..9c296105786
--- /dev/null
+++ b/tests/wpt/tests/fledge/tentative/network.https.window.js
@@ -0,0 +1,260 @@
+// META: script=/resources/testdriver.js
+// META: script=/resources/testdriver-vendor.js
+// META: script=/common/subset-tests.js
+// META: script=/common/utils.js
+// META: script=resources/fledge-util.sub.js
+// META: timeout=long
+// META: variant=?1-5
+// META: variant=?6-last
+
+"use strict";
+
+// These tests focus on Protected Audience network requests - make sure they
+// have no cookies, can set no cookies, and otherwise behave in the expected
+// manner as related to the fetch spec. These tests don't cover additional
+// request or response headers specific to Protected Audience API.
+
+// URL that sets a cookie named "cookie" with a value of "cookie".
+const SET_COOKIE_URL = `${BASE_URL}resources/set-cookie.asis`;
+
+// Returns a URL that stores request headers. Headers can later be retrieved
+// as a name-to-list-of-values mapping with
+// "(await fetchTrackedData(uuid)).trackedHeaders"
+function createHeaderTrackerURL(uuid) {
+ return createTrackerURL(window.location.origin, uuid, 'track_headers');
+}
+
+// Delete all cookies. Separate function so that can be replaced with
+// something else for testing outside of a WPT environment.
+async function deleteAllCookies() {
+ await test_driver.delete_all_cookies();
+}
+
+// Deletes all cookies (to avoid pre-existing cookies causing inconsistent
+// output on failure) and sets a cookie with name "cookie" and a value of
+// "cookie". Adds a cleanup task to delete all cookies again when the test
+// is done.
+async function setCookie(test) {
+ await deleteAllCookies();
+ document.cookie = 'cookie=cookie; path=/'
+ test.add_cleanup(deleteAllCookies);
+}
+
+// Assert that "headers" has a single header with "name", whose value is "value".
+function assertHasHeader(headers, name, value) {
+ assert_equals(JSON.stringify(headers[name]), JSON.stringify([value]),
+ 'Header ' + name);
+}
+
+// Assert that "headers" has no header with "name"
+function assertDoesNotHaveHeader(headers, name) {
+ assert_equals(headers[name], undefined, 'Header ' + name);
+}
+
+subsetTest(promise_test, async test => {
+ const uuid = generateUuid(test);
+ await setCookie(test);
+
+ await joinGroupAndRunBasicFledgeTestExpectingNoWinner(
+ test,
+ { uuid: uuid,
+ interestGroupOverrides: { biddingLogicURL: createHeaderTrackerURL(uuid) }
+ });
+
+ let headers = (await fetchTrackedData(uuid)).trackedHeaders;
+ assertHasHeader(headers, 'accept', 'application/javascript');
+ assertHasHeader(headers, 'sec-fetch-dest', 'empty');
+ assertHasHeader(headers, 'sec-fetch-mode', 'no-cors');
+ assertHasHeader(headers, 'sec-fetch-site', 'same-origin');
+ assertDoesNotHaveHeader(headers, 'cookie');
+ assertDoesNotHaveHeader(headers, 'referer');
+}, 'biddingLogicURL request headers.');
+
+subsetTest(promise_test, async test => {
+ const uuid = generateUuid(test);
+ await deleteAllCookies();
+
+ await joinGroupAndRunBasicFledgeTestExpectingNoWinner(
+ test,
+ { uuid: uuid,
+ interestGroupOverrides: { biddingLogicURL: SET_COOKIE_URL }
+ });
+
+ assert_equals(document.cookie, '');
+ await deleteAllCookies();
+}, 'biddingLogicURL Set-Cookie.');
+
+subsetTest(promise_test, async test => {
+ const uuid = generateUuid(test);
+ await deleteAllCookies();
+
+ await joinGroupAndRunBasicFledgeTestExpectingNoWinner(
+ test,
+ { uuid: uuid,
+ interestGroupOverrides: { biddingLogicURL: SET_COOKIE_URL }
+ });
+
+ assert_equals(document.cookie, '');
+ await deleteAllCookies();
+}, 'biddingLogicURL redirect.');
+
+subsetTest(promise_test, async test => {
+ const uuid = generateUuid(test);
+ await setCookie(test);
+
+ await joinGroupAndRunBasicFledgeTestExpectingNoWinner(
+ test,
+ { uuid: uuid,
+ interestGroupOverrides: { biddingWasmHelperURL: createHeaderTrackerURL(uuid) }
+ });
+
+ let headers = (await fetchTrackedData(uuid)).trackedHeaders;
+ assertHasHeader(headers, 'accept', 'application/wasm');
+ assertHasHeader(headers, 'sec-fetch-dest', 'empty');
+ assertHasHeader(headers, 'sec-fetch-mode', 'no-cors');
+ assertHasHeader(headers, 'sec-fetch-site', 'same-origin');
+ assertDoesNotHaveHeader(headers, 'cookie');
+ assertDoesNotHaveHeader(headers, 'referer');
+}, 'biddingWasmHelperURL request headers.');
+
+subsetTest(promise_test, async test => {
+ const uuid = generateUuid(test);
+ await deleteAllCookies();
+
+ await joinGroupAndRunBasicFledgeTestExpectingNoWinner(
+ test,
+ { uuid: uuid,
+ interestGroupOverrides: { biddingWasmHelperURL: SET_COOKIE_URL }
+ });
+
+ assert_equals(document.cookie, '');
+ await deleteAllCookies();
+}, 'biddingWasmHelperURL Set-Cookie.');
+
+subsetTest(promise_test, async test => {
+ const uuid = generateUuid(test);
+ await setCookie(test);
+
+ await joinGroupAndRunBasicFledgeTestExpectingNoWinner(
+ test,
+ { uuid: uuid,
+ auctionConfigOverrides: { decisionLogicURL: createHeaderTrackerURL(uuid) }
+ });
+
+ let headers = (await fetchTrackedData(uuid)).trackedHeaders;
+ assertHasHeader(headers, 'accept', 'application/javascript');
+ assertHasHeader(headers, 'sec-fetch-dest', 'empty');
+ assertHasHeader(headers, 'sec-fetch-mode', 'no-cors');
+ assertHasHeader(headers, 'sec-fetch-site', 'same-origin');
+ assertDoesNotHaveHeader(headers, 'cookie');
+ assertDoesNotHaveHeader(headers, 'referer');
+}, 'decisionLogicURL request headers.');
+
+subsetTest(promise_test, async test => {
+ const uuid = generateUuid(test);
+ await deleteAllCookies();
+
+ await joinGroupAndRunBasicFledgeTestExpectingNoWinner(
+ test,
+ { uuid: uuid,
+ auctionConfigOverrides: { decisionLogicURL: SET_COOKIE_URL }
+ });
+
+ assert_equals(document.cookie, '');
+ await deleteAllCookies();
+}, 'decisionLogicURL Set-Cookie.');
+
+subsetTest(promise_test, async test => {
+ const uuid = generateUuid(test);
+ await setCookie(test);
+
+ await joinGroupAndRunBasicFledgeTestExpectingWinner(
+ test,
+ { uuid: uuid,
+ interestGroupOverrides: {
+ trustedBiddingSignalsURL: TRUSTED_BIDDING_SIGNALS_URL,
+ trustedBiddingSignalsKeys: ['headers'],
+ biddingLogicURL: createBiddingScriptURL({
+ generateBid:
+ `let headers = trustedBiddingSignals.headers;
+ function checkHeader(name, value) {
+ jsonActualValue = JSON.stringify(headers[name]);
+ if (jsonActualValue !== JSON.stringify([value]))
+ throw "Unexpected " + name + ": " + jsonActualValue;
+ }
+ checkHeader("accept", "application/json");
+ checkHeader("sec-fetch-dest", "empty");
+ checkHeader("sec-fetch-mode", "no-cors");
+ checkHeader("sec-fetch-site", "same-origin");
+ if (headers.cookie !== undefined)
+ throw "Unexpected cookie: " + JSON.stringify(headers.cookie);
+ if (headers.referer !== undefined)
+ throw "Unexpected referer: " + JSON.stringify(headers.referer);`,
+ })
+ }
+ });
+}, 'trustedBiddingSignalsURL request headers.');
+
+subsetTest(promise_test, async test => {
+ const uuid = generateUuid(test);
+ await deleteAllCookies();
+
+ await joinGroupAndRunBasicFledgeTestExpectingWinner(
+ test,
+ { uuid: uuid,
+ interestGroupOverrides: { trustedBiddingSignalsURL: SET_COOKIE_URL }
+ });
+
+ assert_equals(document.cookie, '');
+ await deleteAllCookies();
+}, 'trustedBiddingSignalsURL Set-Cookie.');
+
+subsetTest(promise_test, async test => {
+ const uuid = generateUuid(test);
+ await setCookie(test);
+
+ let renderURL = createRenderURL(uuid, /*script=*/null, /*signalsParam=*/'headers');
+
+ await joinGroupAndRunBasicFledgeTestExpectingWinner(
+ test,
+ { uuid: uuid,
+ interestGroupOverrides: {
+ ads: [{ renderURL: renderURL }]
+ },
+ auctionConfigOverrides: {
+ trustedScoringSignalsURL: TRUSTED_SCORING_SIGNALS_URL,
+ decisionLogicURL: createDecisionScriptURL(uuid,
+ {
+ scoreAd:
+ `let headers = trustedScoringSignals.renderURL["${renderURL}"];
+ function checkHeader(name, value) {
+ jsonActualValue = JSON.stringify(headers[name]);
+ if (jsonActualValue !== JSON.stringify([value]))
+ throw "Unexpected " + name + ": " + jsonActualValue;
+ }
+ checkHeader("accept", "application/json");
+ checkHeader("sec-fetch-dest", "empty");
+ checkHeader("sec-fetch-mode", "no-cors");
+ checkHeader("sec-fetch-site", "same-origin");
+ if (headers.cookie !== undefined)
+ throw "Unexpected cookie: " + JSON.stringify(headers.cookie);
+ if (headers.referer !== undefined)
+ throw "Unexpected referer: " + JSON.stringify(headers.referer);`,
+ })
+ }
+ });
+}, 'trustedScoringSignalsURL request headers.');
+
+subsetTest(promise_test, async test => {
+ const uuid = generateUuid(test);
+ await deleteAllCookies();
+
+ await joinGroupAndRunBasicFledgeTestExpectingWinner(
+ test,
+ { uuid: uuid,
+ auctionConfigOverrides: { trustedScoringSignalsURL: SET_COOKIE_URL }
+ });
+
+ assert_equals(document.cookie, '');
+ await deleteAllCookies();
+}, 'trustedScoringSignalsURL Set-Cookie.');
diff --git a/tests/wpt/tests/fledge/tentative/resources/bidding-logic.sub.py b/tests/wpt/tests/fledge/tentative/resources/bidding-logic.sub.py
index 58fe220880a..c0d6114ab2c 100644
--- a/tests/wpt/tests/fledge/tentative/resources/bidding-logic.sub.py
+++ b/tests/wpt/tests/fledge/tentative/resources/bidding-logic.sub.py
@@ -37,10 +37,15 @@ def main(request, response):
# Use bid query param if present. Otherwise, use a bid of 9.
bid = (request.GET.first(b"bid", None) or b"9").decode("ASCII")
+ bidCurrency = ""
+ bidCurrencyParam = request.GET.first(b"bidCurrency", None)
+ if bidCurrencyParam != None:
+ bidCurrency = "bidCurrency: '" + bidCurrencyParam.decode("ASCII") + "',"
+
allowComponentAuction = ""
allowComponentAuctionParam = request.GET.first(b"allowComponentAuction", None)
if allowComponentAuctionParam != None:
- allowComponentAuction = f"allowComponentAuction: {allowComponentAuctionParam.decode('ASCII')},"
+ allowComponentAuction = f"allowComponentAuction: {allowComponentAuctionParam.decode('ASCII')},"
body += f"""
function generateBid(interestGroup, auctionSignals, perBuyerSignals,
@@ -49,6 +54,7 @@ def main(request, response):
{{{{GET[generateBid]}}}};
return {{
bid: {bid},
+ {bidCurrency}
{allowComponentAuction}
render: interestGroup.ads[0].renderURL
}};
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 d500307a079..e19d85a558f 100644
--- a/tests/wpt/tests/fledge/tentative/resources/fledge-util.sub.js
+++ b/tests/wpt/tests/fledge/tentative/resources/fledge-util.sub.js
@@ -80,7 +80,31 @@ function generateUuid(test) {
return uuid;
}
-// Repeatedly requests "request_list" URL until exactly the entries in
+// Helper to fetch "tracked_data" URL to fetch all data recorded by the
+// tracker URL associated with "uuid". Throws on error, including if
+// the retrieved object's errors field is non-empty.
+async function fetchTrackedData(uuid) {
+ let trackedRequestsURL = createTrackerURL(window.location.origin, uuid,
+ 'tracked_data');
+ let response = await fetch(trackedRequestsURL,
+ {credentials: 'omit', mode: 'cors'});
+ let trackedData = await response.json();
+
+ // Fail on fetch error.
+ if (trackedData.error) {
+ throw trackedRequestsURL + ' fetch failed:' + JSON.stringify(trackedData);
+ }
+
+ // Fail on errors reported by the tracker script.
+ if (trackedData.errors.length > 0) {
+ throw 'Errors reported by request-tracker.py:' +
+ JSON.stringify(trackedData.errors);
+ }
+
+ return trackedData;
+}
+
+// Repeatedly requests "tracked_data" URL until exactly the entries in
// "expectedRequests" have been observed by the request tracker script (in
// any order, since report URLs are not guaranteed to be sent in any order).
//
@@ -90,36 +114,21 @@ function generateUuid(test) {
// If any other strings are received from the tracking script, or the tracker
// script reports an error, fails the test.
async function waitForObservedRequests(uuid, expectedRequests) {
- let trackedRequestsURL = createTrackerURL(window.location.origin, uuid,
- 'request_list');
- // Sort array for easier comparison, since order doesn't matter.
- expectedRequests.sort();
- while (true) {
- let response = await fetch(trackedRequestsURL,
- {credentials: 'omit', mode: 'cors'});
- let trackerData = await response.json();
+ // 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>'));
- // Fail on fetch error.
- if (trackerData.error) {
- throw trackedRequestsURL + ' fetch failed:' +
- JSON.stringify(trackerData);
- }
+ while (true) {
+ let trackedData = await fetchTrackedData(uuid);
- // Fail on errors reported by the tracker script.
- if (trackerData.errors.length > 0) {
- throw 'Errors reported by request-tracker.py:' +
- JSON.stringify(trackerData.errors);
- }
+ // Clean up "trackedRequests" in same manner as "expectedRequests".
+ let trackedRequests = trackedData.trackedRequests.sort().map(
+ (url) => url.replace(uuid, '<uuid>'));
// If expected number of requests have been observed, compare with list of
// all expected requests and exit.
- let trackedRequests = trackerData.trackedRequests;
if (trackedRequests.length == expectedRequests.length) {
- // Hide the uuid content in order to have a static expected file.
- assert_array_equals(trackedRequests.sort().map((url) =>
- url.replace(uuid, '<uuid>')),
- expectedRequests.map((url) =>
- url.replace(uuid, '<uuid>')));
+ assert_array_equals(trackedRequests, expectedRequests);
break;
}
@@ -127,9 +136,7 @@ async function waitForObservedRequests(uuid, expectedRequests) {
// compare what's been received so far, to have a greater chance to fail
// rather than hang on error.
for (const trackedRequest of trackedRequests) {
- assert_in_array(trackedRequest.replace(uuid, '<uuid>'),
- expectedRequests.sort().map((url) =>
- url.replace(uuid, '<uuid>')));
+ assert_in_array(trackedRequest, expectedRequests);
}
}
}
@@ -151,6 +158,8 @@ function createBiddingScriptURL(params = {}) {
url.searchParams.append('error', params.error);
if (params.bid)
url.searchParams.append('bid', params.bid);
+ if (params.bidCurrency)
+ url.searchParams.append('bidCurrency', params.bidCurrency);
if (params.allowComponentAuction !== undefined)
url.searchParams.append('allowComponentAuction', JSON.stringify(params.allowComponentAuction))
return url.toString();
diff --git a/tests/wpt/tests/fledge/tentative/resources/fledge_http_server_util.py b/tests/wpt/tests/fledge/tentative/resources/fledge_http_server_util.py
new file mode 100644
index 00000000000..a5c9c9715aa
--- /dev/null
+++ b/tests/wpt/tests/fledge/tentative/resources/fledge_http_server_util.py
@@ -0,0 +1,11 @@
+# Takes a map of header names to list of values that are all binary strings
+# and returns an otherwise identical map where keys and values have both been
+# converted to ASCII strings.
+def headersToAscii(headers):
+ header_map = {}
+ for pair in headers.items():
+ values = []
+ for value in pair[1]:
+ values.append(value.decode("ASCII"))
+ header_map[pair[0].decode("ASCII")] = values
+ return header_map
diff --git a/tests/wpt/tests/fledge/tentative/resources/request-tracker.py b/tests/wpt/tests/fledge/tentative/resources/request-tracker.py
index 46da796f301..9fe20bf83ac 100644
--- a/tests/wpt/tests/fledge/tentative/resources/request-tracker.py
+++ b/tests/wpt/tests/fledge/tentative/resources/request-tracker.py
@@ -2,6 +2,7 @@ import mimetypes
import os
import json
import wptserve.stash
+from fledge.tentative.resources.fledge_http_server_util import headersToAscii
from wptserve.utils import isomorphic_decode, isomorphic_encode
@@ -12,14 +13,18 @@ from wptserve.utils import isomorphic_decode, isomorphic_encode
# clean up after themselves, or that are running concurrently, from interfering
# with other tests.
#
-# Each uuid has a stash entry with a dictionary with two entries:
+# Each uuid has a stash entry with a dictionary with the following entries:
# "trackedRequests" is a list of all observed requested URLs with a
# dispatch of "track_get" or "track_post". POSTS are in the format
# "<url>, body: <body>".
+# "trackedHeaders" is an object mapping HTTP header names to lists
+# of received HTTP header values for a single request with a
+# dispatch of "track_headers".
# "errors" is a list of an errors that occurred.
#
-# A dispatch of "request_list" will return the "trackedRequests" dictionary
-# associated with the in uuid, as a JSON string.
+# A dispatch of "tracked_data" will return all tracked information associated
+# with the uuid, as a JSON string. The "errors" field should be checked by
+# the caller before checking other fields.
#
# A dispatch of "clean_up" will delete all information associated with the uuid.
def main(request, response):
@@ -38,7 +43,7 @@ def main(request, response):
with stash.lock:
# Take ownership of stashed entry, if any. This removes the entry of the
# stash.
- server_state = stash.take(uuid) or {"trackedRequests": [], "errors": []}
+ server_state = stash.take(uuid) or {"trackedRequests": [], "errors": [], "trackedHeaders": None}
# Clear the entire stash. No work to do, since stash entry was already
# removed.
@@ -48,7 +53,7 @@ def main(request, response):
# Return the list of entries in the stash. Need to add data back to the
# stash first.
- if dispatch == b"request_list":
+ if dispatch == b"tracked_data":
stash.put(uuid, server_state)
return simple_response(request, response, 200, b"OK",
json.dumps(server_state))
@@ -66,7 +71,7 @@ def main(request, response):
# Tracks a request that's expected to be a POST.
# In addition to the method, check the Content-Type, which is currently
- # always text/plain, and compare the body against the expected body.
+ # always text/plain. The request body is stored in trackedRequests.
if dispatch == b"track_post":
contentType = request.headers.get(b"Content-Type", b"missing")
if request.method != "POST":
@@ -82,6 +87,16 @@ def main(request, response):
stash.put(uuid, server_state)
return simple_response(request, response, 200, b"OK", b"")
+ # Tracks request headers for a single request.
+ if dispatch == b"track_headers":
+ if server_state["trackedHeaders"] != None:
+ server_state["errors"].append("Second track_headers request received.")
+ else:
+ server_state["trackedHeaders"] = headersToAscii(request.headers)
+
+ stash.put(uuid, server_state)
+ return simple_response(request, response, 200, b"OK", b"")
+
# Report unrecognized dispatch line.
server_state["errors"].append(
request.url + " request with unknown dispatch value received: " +
diff --git a/tests/wpt/tests/fledge/tentative/resources/set-cookie.asis b/tests/wpt/tests/fledge/tentative/resources/set-cookie.asis
new file mode 100644
index 00000000000..96d9f07c578
--- /dev/null
+++ b/tests/wpt/tests/fledge/tentative/resources/set-cookie.asis
@@ -0,0 +1,3 @@
+HTTP/1.1 200 Ok
+Set-Cookie: cookie=cookie; path=/
+
diff --git a/tests/wpt/tests/fledge/tentative/resources/trusted-bidding-signals.py b/tests/wpt/tests/fledge/tentative/resources/trusted-bidding-signals.py
index 86e4db8ad44..16272afc71c 100644
--- a/tests/wpt/tests/fledge/tentative/resources/trusted-bidding-signals.py
+++ b/tests/wpt/tests/fledge/tentative/resources/trusted-bidding-signals.py
@@ -1,5 +1,6 @@
import json
from urllib.parse import unquote_plus
+from fledge.tentative.resources.fledge_http_server_util import headersToAscii
# Script to generate trusted bidding signals. The responses depends on the
# keys and interestGroupNames - some result in entire response failures, others
@@ -99,6 +100,8 @@ def main(request, response):
value = json.dumps(interestGroupNames)
elif key == "hostname":
value = request.GET.first(b"hostname", b"not-found").decode("ASCII")
+ elif key == "headers":
+ value = headersToAscii(request.headers)
responseBody["keys"][key] = value
if "data-version" in interestGroupNames:
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 43ff772a0e3..fc6ec79096c 100644
--- a/tests/wpt/tests/fledge/tentative/resources/trusted-scoring-signals.py
+++ b/tests/wpt/tests/fledge/tentative/resources/trusted-scoring-signals.py
@@ -1,5 +1,6 @@
import json
from urllib.parse import unquote_plus, urlparse
+from fledge.tentative.resources.fledge_http_server_util import headersToAscii
# Script to generate trusted scoring signals. The responses depends on the
# query strings in the ads Urls - some result in entire response failures,
@@ -117,6 +118,8 @@ def main(request, response):
value = {"a":"b", "c":["d"]}
elif signalsParam == "hostname":
value = request.GET.first(b"hostname", b"not-found").decode("ASCII")
+ elif signalsParam == "headers":
+ value = headersToAscii(request.headers)
if addValue:
if urlList["type"] not in responseBody:
responseBody[urlList["type"]] = {}
diff --git a/tests/wpt/tests/fullscreen/api/fullscreen-reordering.html b/tests/wpt/tests/fullscreen/api/fullscreen-reordering.html
index 4b394bc20fc..1aaf3c37c04 100644
--- a/tests/wpt/tests/fullscreen/api/fullscreen-reordering.html
+++ b/tests/wpt/tests/fullscreen/api/fullscreen-reordering.html
@@ -4,7 +4,7 @@
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
-<script src="../../html/semantics/popovers/resources/popover-utils.js"></script>
+<script src="/common/top-layer.js"></script>
<div class="elements">
<div id="A">Element A</div>
diff --git a/tests/wpt/tests/generic-sensor/generic-sensor-iframe-tests.sub.js b/tests/wpt/tests/generic-sensor/generic-sensor-iframe-tests.sub.js
index 7b816c01c74..8f13bd778e0 100644
--- a/tests/wpt/tests/generic-sensor/generic-sensor-iframe-tests.sub.js
+++ b/tests/wpt/tests/generic-sensor/generic-sensor-iframe-tests.sub.js
@@ -1,152 +1,295 @@
-function send_message_to_iframe(iframe, message, reply) {
- if (reply === undefined) {
- reply = 'success';
- }
-
+function send_message_to_iframe(iframe, message) {
return new Promise((resolve, reject) => {
window.addEventListener('message', (e) => {
+ // The usage of test_driver.set_test_context() in
+ // iframe_sensor_handler.html causes unrelated messages to be sent as
+ // well. We just need to ignore them here.
+ if (!e.data.command) {
+ return;
+ }
+
if (e.data.command !== message.command) {
- reject(`Expected reply with command '${message.command}', got '${e.data.command}' instead`);
+ reject(`Expected reply with command '${message.command}', got '${
+ e.data.command}' instead`);
return;
}
- if (e.data.result === reply) {
- resolve();
- } else {
- reject(`Got unexpected reply '${e.data.result}' to command '${message.command}', expected '${reply}'`);
+ if (e.data.error) {
+ reject(e.data.error);
+ return;
}
- }, { once: true });
+ resolve(e.data.result);
+ });
iframe.contentWindow.postMessage(message, '*');
});
}
-function run_generic_sensor_iframe_tests(sensorName) {
+function run_generic_sensor_iframe_tests(sensorData, readingData) {
+ validate_sensor_data(sensorData);
+ validate_reading_data(readingData);
+
+ const {sensorName, permissionName, testDriverName} = sensorData;
const sensorType = self[sensorName];
const featurePolicies = get_feature_policies_for_sensor(sensorName);
- sensor_test(async t => {
- assert_implements(sensorName in self, `${sensorName} is not supported.`);
+ // When comparing timestamps in the tests below, we need to account for small
+ // deviations coming from the way time is coarsened according to the High
+ // Resolution Time specification, even more so when we need to translate
+ // timestamps from different documents with different time origins.
+ // 0.5 is 500 microseconds, which is acceptable enough given that even a high
+ // sensor frequency beyond what is usually allowed like 100Hz has a period
+ // much larger than 0.5ms.
+ const ALLOWED_JITTER_IN_MS = 0.5;
+
+ function sensor_test(func, name, properties) {
+ promise_test(async t => {
+ assert_implements(sensorName in self, `${sensorName} is not supported.`);
+ const readings = new RingBuffer(readingData.readings);
+ return func(t, readings);
+ }, name, properties);
+ }
+
+ sensor_test(async (t, readings) => {
+ // This is a specialized EventWatcher that works with a sensor inside a
+ // cross-origin iframe. We cannot manipulate the sensor object there
+ // directly from this frame, so we need the iframe to send us a message
+ // when the "reading" event is fired, and we decide whether we were
+ // expecting for it or not. This should be instantiated early in the test
+ // to catch as many unexpected events as possible.
+ class IframeSensorReadingEventWatcher {
+ constructor(test_obj) {
+ this.resolve_ = null;
+
+ window.onmessage = test_obj.step_func((ev) => {
+ // Unrelated message, ignore.
+ if (!ev.data.eventName) {
+ return;
+ }
+
+ assert_equals(
+ ev.data.eventName, 'reading', 'Expecting a "reading" event');
+ assert_true(
+ !!this.resolve_,
+ 'Received "reading" event from iframe but was not expecting one');
+ const resolveFunc = this.resolve_;
+ this.resolve_ = null;
+ resolveFunc(ev.data.serializedSensor);
+ });
+ }
+
+ wait_for_reading() {
+ return new Promise(resolve => {
+ this.resolve_ = resolve;
+ });
+ }
+ };
+
+ // Create main frame sensor.
+ await test_driver.set_permission({name: permissionName}, 'granted');
+ await test_driver.create_virtual_sensor(testDriverName);
+ const sensor = new sensorType();
+ t.add_cleanup(async () => {
+ sensor.stop();
+ await test_driver.remove_virtual_sensor(testDriverName);
+ });
+ const sensorWatcher =
+ new EventWatcher(t, sensor, ['activate', 'reading', 'error']);
+
+ // Create cross-origin iframe and a sensor inside it.
const iframe = document.createElement('iframe');
iframe.allow = featurePolicies.join(';') + ';';
- iframe.src = 'https://{{domains[www1]}}:{{ports[https][0]}}/generic-sensor/resources/iframe_sensor_handler.html';
-
- // Create sensor inside cross-origin nested browsing context.
+ iframe.src =
+ 'https://{{domains[www1]}}:{{ports[https][0]}}/generic-sensor/resources/iframe_sensor_handler.html';
const iframeLoadWatcher = new EventWatcher(t, iframe, 'load');
document.body.appendChild(iframe);
t.add_cleanup(async () => {
- await send_message_to_iframe(iframe, { command: 'reset_sensor_backend' });
+ await send_message_to_iframe(iframe, {command: 'stop_sensor'});
iframe.parentNode.removeChild(iframe);
});
await iframeLoadWatcher.wait_for('load');
- await send_message_to_iframe(iframe, {command: 'create_sensor',
- type: sensorName});
+ const iframeSensorWatcher = new IframeSensorReadingEventWatcher(t);
+ await send_message_to_iframe(
+ iframe, {command: 'create_sensor', sensorData});
- // Focus on the main frame and test that sensor receives readings.
+ // Start the test by focusing the main frame. It is already focused by
+ // default, but this makes the test easier to follow.
+ // When the main frame is focused, it sensor is expected to fire "reading"
+ // events and provide access to new reading values while the sensor in the
+ // cross-origin iframe is not.
window.focus();
- const sensor = new sensorType();
- const sensorWatcher = new EventWatcher(t, sensor, ['reading', 'error']);
+
+ // Start both sensors. They should both have the same state: active, but no
+ // readings have been provided to them yet.
+ await send_message_to_iframe(iframe, {command: 'start_sensor'});
sensor.start();
+ await sensorWatcher.wait_for('activate');
+ assert_false(
+ await send_message_to_iframe(iframe, {command: 'has_reading'}));
+ assert_false(sensor.hasReading);
+
+ // We store `reading` here because we want to make sure the very same
+ // value is accepted later.
+ const reading = readings.next().value;
+ await Promise.all([
+ sensorWatcher.wait_for('reading'),
+ test_driver.update_virtual_sensor(testDriverName, reading),
+ // Since we do not wait for the iframe sensor's "reading" event, it could
+ // arguably be delivered later. There are enough async calls happening
+ // that IframeSensorReadingEventWatcher would end up catching it and
+ // throwing an error.
+ ]);
+ assert_true(sensor.hasReading);
+ assert_false(
+ await send_message_to_iframe(iframe, {command: 'has_reading'}));
- await sensorWatcher.wait_for('reading');
- const cachedTimeStamp = sensor.timestamp;
+ // Save sensor data for later before the sensor is stopped.
+ const savedMainFrameSensorReadings = serialize_sensor_data(sensor);
- // Focus on the cross-origin frame and verify that sensor reading updates in
- // the top level browsing context are suspended.
+ sensor.stop();
+ await send_message_to_iframe(iframe, {command: 'stop_sensor'});
+
+ // Now focus the cross-origin iframe. The situation should be the opposite:
+ // the sensor in the main frame should not fire any "reading" events or
+ // provide access to updated readings, but the sensor in the iframe should.
iframe.contentWindow.focus();
+
+ // Start both sensors. They should both have the same state: active, but no
+ // readings have been provided to them yet.
await send_message_to_iframe(iframe, {command: 'start_sensor'});
+ sensor.start();
+ await sensorWatcher.wait_for('activate');
+ assert_false(
+ await send_message_to_iframe(iframe, {command: 'has_reading'}));
+ assert_false(sensor.hasReading);
- // Focus on the main frame, verify that sensor reading updates are resumed.
- window.focus();
- await sensorWatcher.wait_for('reading');
- assert_greater_than(sensor.timestamp, cachedTimeStamp);
- sensor.stop();
+ const [serializedIframeSensor] = await Promise.all([
+ iframeSensorWatcher.wait_for_reading(),
+ test_driver.update_virtual_sensor(testDriverName, reading),
+ ]);
+ assert_true(await send_message_to_iframe(iframe, {command: 'has_reading'}));
+ assert_false(sensor.hasReading);
- // Verify that sensor in cross-origin frame is suspended.
- await send_message_to_iframe(iframe, {command: 'is_sensor_suspended'}, true);
- }, `${sensorName}: sensor is suspended and resumed when focus traverses from\
- to cross-origin frame`);
+ assert_sensor_reading_is_null(sensor);
- sensor_test(async t => {
- assert_implements(sensorName in self, `${sensorName} is not supported.`);
+ assert_sensor_reading_equals(
+ savedMainFrameSensorReadings, serializedIframeSensor,
+ {ignoreTimestamps: true});
+
+ // We could check that serializedIframeSensor.timestamp (adjusted to this
+ // frame by adding the iframe's timeOrigin and substracting
+ // performance.timeOrigin) is greater than
+ // savedMainFrameSensorReadings.timestamp (or other timestamps prior to the
+ // last test_driver.update_virtual_sensor() call), but this is surprisingly
+ // tricky and flaky due to the fact that we are using timestamps from
+ // cross-origin frames.
+ //
+ // On Chrome on Windows (M120 at the time of writing), for example, the
+ // difference between timeOrigin values is sometimes off by more than 10ms
+ // from the real difference, and allowing for this much jitter makes the
+ // test not test something meaningful.
+ }, `${sensorName}: unfocused sensors in cross-origin frames are not updated`);
+
+ sensor_test(async (t, readings) => {
+ // Create main frame sensor.
+ await test_driver.set_permission({name: permissionName}, 'granted');
+ await test_driver.create_virtual_sensor(testDriverName);
+ const sensor = new sensorType();
+ t.add_cleanup(async () => {
+ sensor.stop();
+ await test_driver.remove_virtual_sensor(testDriverName);
+ });
+ const sensorWatcher =
+ new EventWatcher(t, sensor, ['activate', 'reading', 'error']);
+
+ // Create same-origin iframe and a sensor inside it.
const iframe = document.createElement('iframe');
iframe.allow = featurePolicies.join(';') + ';';
- iframe.src = 'https://{{host}}:{{ports[https][0]}}/generic-sensor/resources/iframe_sensor_handler.html';
-
+ iframe.src = 'https://{{host}}:{{ports[https][0]}}/resources/blank.html';
// Create sensor inside same-origin nested browsing context.
const iframeLoadWatcher = new EventWatcher(t, iframe, 'load');
document.body.appendChild(iframe);
- t.add_cleanup(async () => {
- await send_message_to_iframe(iframe, { command: 'reset_sensor_backend' });
+ t.add_cleanup(() => {
+ if (iframeSensor) {
+ iframeSensor.stop();
+ }
iframe.parentNode.removeChild(iframe);
});
await iframeLoadWatcher.wait_for('load');
- await send_message_to_iframe(iframe, {command: 'create_sensor',
- type: sensorName});
+ // We deliberately create the sensor here instead of using
+ // send_messge_to_iframe() because this is a same-origin iframe, and we can
+ // therefore use EventWatcher() to wait for "reading" events a lot more
+ // easily.
+ const iframeSensor = new iframe.contentWindow[sensorName]();
+ const iframeSensorWatcher =
+ new EventWatcher(t, iframeSensor, ['activate', 'error', 'reading']);
- // Focus on main frame and test that sensor receives readings.
- window.focus();
- const sensor = new sensorType({
- // generic_sensor_mocks.js uses a default frequency of 5Hz for sensors.
- // We deliberately use a higher frequency here to make it easier to spot
- // spurious, unexpected 'reading' events caused by the main frame's
- // sensor not stopping early enough.
- // TODO(rakuco): Create a constant with the 5Hz default frequency instead
- // of using magic numbers.
- frequency: 15
- });
- const sensorWatcher = new EventWatcher(t, sensor, ['reading', 'error']);
- sensor.start();
- await sensorWatcher.wait_for('reading');
- let cachedTimeStamp = sensor.timestamp;
-
- // Stop sensor in main frame, so that sensorWatcher would not receive
- // readings while sensor in iframe is started. Sensors that are active and
- // belong to the same-origin context are not suspended automatically when
- // focus changes to another same-origin iframe, so if we do not explicitly
- // stop them we may receive extra 'reading' events that cause the test to
- // fail (see e.g. https://crbug.com/857520).
- sensor.stop();
+ // Focus a different same-origin window each time and check that everything
+ // works the same.
+ for (const windowObject of [window, iframe.contentWindow]) {
+ windowObject.focus();
- iframe.contentWindow.focus();
- await send_message_to_iframe(iframe, {command: 'start_sensor'});
+ iframeSensor.start();
+ sensor.start();
+ await Promise.all([
+ iframeSensorWatcher.wait_for('activate'),
+ sensorWatcher.wait_for('activate')
+ ]);
- // Start sensor on main frame, verify that readings are updated.
- window.focus();
- sensor.start();
- await sensorWatcher.wait_for('reading');
- assert_greater_than(sensor.timestamp, cachedTimeStamp);
- cachedTimeStamp = sensor.timestamp;
- sensor.stop();
+ assert_false(sensor.hasReading);
+ assert_false(iframeSensor.hasReading);
- // Verify that sensor in nested browsing context is not suspended.
- await send_message_to_iframe(iframe, {command: 'is_sensor_suspended'}, false);
+ // We store `reading` here because we want to make sure the very same
+ // value is accepted later.
+ const reading = readings.next().value;
+ await Promise.all([
+ test_driver.update_virtual_sensor(testDriverName, reading),
+ iframeSensorWatcher.wait_for('reading'),
+ sensorWatcher.wait_for('reading')
+ ]);
- // Verify that sensor in top level browsing context is receiving readings.
- iframe.contentWindow.focus();
- sensor.start();
- await sensorWatcher.wait_for('reading');
- assert_greater_than(sensor.timestamp, cachedTimeStamp);
- sensor.stop();
- }, `${sensorName}: sensor is not suspended when focus traverses from\
- to same-origin frame`);
+ assert_greater_than(
+ iframe.contentWindow.performance.timeOrigin, performance.timeOrigin,
+ 'iframe\'s time origin must be higher than the main window\'s');
+
+ // Check that the timestamps are similar enough to indicate that this is
+ // the same reading that was delivered to both sensors.
+ // The values are not identical due to how high resolution time is
+ // coarsened.
+ const translatedIframeSensorTimestamp = iframeSensor.timestamp +
+ iframe.contentWindow.performance.timeOrigin - performance.timeOrigin;
+ assert_approx_equals(
+ translatedIframeSensorTimestamp, sensor.timestamp,
+ ALLOWED_JITTER_IN_MS);
- sensor_test(async t => {
+ // Do not compare timestamps here because of the reasons above.
+ assert_sensor_reading_equals(
+ sensor, iframeSensor, {ignoreTimestamps: true});
+
+ // Stop all sensors so we can use the same value in `reading` on every
+ // loop iteration.
+ iframeSensor.stop();
+ sensor.stop();
+ }
+ }, `${sensorName}: sensors in same-origin frames are updated if one of the frames is focused`);
+
+ promise_test(async t => {
assert_implements(sensorName in self, `${sensorName} is not supported.`);
const iframe = document.createElement('iframe');
iframe.allow = featurePolicies.join(';') + ';';
- iframe.src = 'https://{{host}}:{{ports[https][0]}}/generic-sensor/resources/iframe_sensor_handler.html';
+ iframe.src =
+ 'https://{{host}}:{{ports[https][0]}}/generic-sensor/resources/iframe_sensor_handler.html';
- // Create sensor in the iframe.
const iframeLoadWatcher = new EventWatcher(t, iframe, 'load');
document.body.appendChild(iframe);
await iframeLoadWatcher.wait_for('load');
- // This is required for the JS Mojo backend to be initialized in the
- // iframe.
- await send_message_to_iframe(iframe, {command: 'create_sensor',
- type: sensorName});
+
+ // Create sensor in the iframe.
+ await test_driver.set_permission({name: permissionName}, 'granted');
+ await test_driver.create_virtual_sensor(testDriverName);
iframe.contentWindow.focus();
const iframeSensor = new iframe.contentWindow[sensorName]();
- t.add_cleanup(() => {
+ t.add_cleanup(async () => {
iframeSensor.stop();
+ await test_driver.remove_virtual_sensor(testDriverName);
});
const sensorWatcher = new EventWatcher(t, iframeSensor, ['activate']);
iframeSensor.start();
@@ -161,24 +304,25 @@ function run_generic_sensor_iframe_tests(sensorName) {
window.focus();
}, `${sensorName}: losing a document's frame with an active sensor does not crash`);
- sensor_test(async t => {
+ promise_test(async t => {
assert_implements(sensorName in self, `${sensorName} is not supported.`);
const iframe = document.createElement('iframe');
iframe.allow = featurePolicies.join(';') + ';';
- iframe.src = 'https://{{host}}:{{ports[https][0]}}/generic-sensor/resources/iframe_sensor_handler.html';
+ iframe.src =
+ 'https://{{host}}:{{ports[https][0]}}/generic-sensor/resources/iframe_sensor_handler.html';
- // Create sensor in the iframe (we do not care whether this is a
- // cross-origin nested context in this test).
const iframeLoadWatcher = new EventWatcher(t, iframe, 'load');
document.body.appendChild(iframe);
await iframeLoadWatcher.wait_for('load');
- // The purpose of this message is to initialize the mock backend in the
- // iframe. We are not going to use the sensor created there.
- await send_message_to_iframe(iframe, {command: 'create_sensor',
- type: sensorName});
-
+ // Create sensor in the iframe.
+ await test_driver.set_permission({name: permissionName}, 'granted');
+ await test_driver.create_virtual_sensor(testDriverName);
const iframeSensor = new iframe.contentWindow[sensorName]();
+ t.add_cleanup(async () => {
+ iframeSensor.stop();
+ await test_driver.remove_virtual_sensor(testDriverName);
+ });
assert_not_equals(iframeSensor, null);
// Remove iframe from main document. |iframeSensor| no longer has a
diff --git a/tests/wpt/tests/generic-sensor/generic-sensor-tests.js b/tests/wpt/tests/generic-sensor/generic-sensor-tests.js
index 3c8f478c541..3b23fe89191 100644
--- a/tests/wpt/tests/generic-sensor/generic-sensor-tests.js
+++ b/tests/wpt/tests/generic-sensor/generic-sensor-tests.js
@@ -14,289 +14,344 @@
// |verificationFunction| is called to verify that a given reading matches a
// value in |expectedReadings|.
// |featurePolicies| represents |sensorName|'s associated sensor feature name.
+function runGenericSensorTests(sensorData, readingData) {
+ validate_sensor_data(sensorData);
+ validate_reading_data(readingData);
-function runGenericSensorTests(sensorName,
- readingData,
- verificationFunction,
- featurePolicies) {
+ const {sensorName, permissionName, testDriverName, featurePolicyNames} =
+ sensorData;
const sensorType = self[sensorName];
- function validateReadingFormat(data) {
- return Array.isArray(data) && data.every(element => Array.isArray(element));
- }
-
- const { readings, expectedReadings, expectedRemappedReadings } = readingData;
- if (!validateReadingFormat(readings)) {
- throw new TypeError('readingData.readings must be an array of arrays.');
- }
- if (!validateReadingFormat(expectedReadings)) {
- throw new TypeError('readingData.expectedReadings must be an array of ' +
- 'arrays.');
- }
- if (readings.length < expectedReadings.length) {
- throw new TypeError('readingData.readings\' length must be bigger than ' +
- 'or equal to readingData.expectedReadings\' length.');
- }
- if (expectedRemappedReadings &&
- !validateReadingFormat(expectedRemappedReadings)) {
- throw new TypeError('readingData.expectedRemappedReadings must be an ' +
- 'array of arrays.');
- }
- if (expectedRemappedReadings &&
- expectedReadings.length != expectedRemappedReadings.length) {
- throw new TypeError('readingData.expectedReadings and ' +
- 'readingData.expectedRemappedReadings must have the same ' +
- 'length.');
- }
+ function sensor_test(func, name, properties) {
+ promise_test(async t => {
+ assert_implements(sensorName in self, `${sensorName} is not supported.`);
- sensor_test(async (t, sensorProvider) => {
- assert_implements(sensorName in self, `${sensorName} is not supported.`);
- sensorProvider.setGetSensorShouldFail(sensorName, true);
- const sensor = new sensorType;
- const sensorWatcher = new EventWatcher(t, sensor, ["reading", "error"]);
- sensor.start();
+ const readings = new RingBuffer(readingData.readings);
+ const expectedReadings = new RingBuffer(readingData.expectedReadings);
+ const expectedRemappedReadings = readingData.expectedRemappedReadings ?
+ new RingBuffer(readingData.expectedRemappedReadings) :
+ undefined;
- const event = await sensorWatcher.wait_for("error");
+ return func(t, readings, expectedReadings, expectedRemappedReadings);
+ }, name, properties);
+ }
- assert_false(sensor.activated);
- assert_equals(event.error.name, 'NotReadableError');
- }, `${sensorName}: Test that onerror is sent when sensor is not supported.`);
+ sensor_test(async t => {
+ await test_driver.set_permission({name: permissionName}, 'denied');
- sensor_test(async (t, sensorProvider) => {
- assert_implements(sensorName in self, `${sensorName} is not supported.`);
- sensorProvider.setPermissionsDenied(sensorName, true);
+ await test_driver.create_virtual_sensor(testDriverName);
const sensor = new sensorType;
- const sensorWatcher = new EventWatcher(t, sensor, ["reading", "error"]);
+ t.add_cleanup(async () => {
+ sensor.stop();
+ await test_driver.remove_virtual_sensor(testDriverName);
+ });
+ const sensorWatcher = new EventWatcher(t, sensor, ['reading', 'error']);
sensor.start();
- const event = await sensorWatcher.wait_for("error");
+ const event = await sensorWatcher.wait_for('error');
assert_false(sensor.activated);
assert_equals(event.error.name, 'NotAllowedError');
}, `${sensorName}: Test that onerror is sent when permissions are not\
granted.`);
- sensor_test(async (t, sensorProvider) => {
- assert_implements(sensorName in self, `${sensorName} is not supported.`);
- const sensor = new sensorType({frequency: 560});
- const sensorWatcher = new EventWatcher(t, sensor, ["reading", "error"]);
- sensor.start();
+ sensor_test(async t => {
+ await test_driver.set_permission({name: permissionName}, 'granted');
- const mockSensor = await sensorProvider.getCreatedSensor(sensorName);
- mockSensor.setStartShouldFail(true);
+ await test_driver.create_virtual_sensor(testDriverName, {connected: false});
+ const sensor = new sensorType;
+ t.add_cleanup(async () => {
+ sensor.stop();
+ await test_driver.remove_virtual_sensor(testDriverName);
+ });
+ const sensorWatcher = new EventWatcher(t, sensor, ['reading', 'error']);
- const event = await sensorWatcher.wait_for("error");
+ sensor.start();
+
+ const event = await sensorWatcher.wait_for('error');
assert_false(sensor.activated);
assert_equals(event.error.name, 'NotReadableError');
}, `${sensorName}: Test that onerror is send when start() call has failed.`);
- sensor_test(async (t, sensorProvider) => {
- assert_implements(sensorName in self, `${sensorName} is not supported.`);
+ sensor_test(async t => {
+ await test_driver.set_permission({name: permissionName}, 'granted');
+
+ await test_driver.create_virtual_sensor(testDriverName);
+
const sensor = new sensorType({frequency: 560});
- const sensorWatcher = new EventWatcher(t, sensor, ["activate", "error"]);
+ t.add_cleanup(async () => {
+ sensor.stop();
+ await test_driver.remove_virtual_sensor(testDriverName);
+ });
+ const sensorWatcher = new EventWatcher(t, sensor, ['activate', 'error']);
sensor.start();
- const mockSensor = await sensorProvider.getCreatedSensor(sensorName);
-
- await sensorWatcher.wait_for("activate");
+ await sensorWatcher.wait_for('activate');
+ const mockSensorInfo =
+ await test_driver.get_virtual_sensor_information(testDriverName);
- assert_less_than_equal(mockSensor.getSamplingFrequency(), 60);
- sensor.stop();
- assert_false(sensor.activated);
+ assert_less_than_equal(mockSensorInfo.requestedSamplingFrequency, 60);
}, `${sensorName}: Test that frequency is capped to allowed maximum.`);
- sensor_test(async (t, sensorProvider) => {
- assert_implements(sensorName in self, `${sensorName} is not supported.`);
+ sensor_test(async t => {
+ await test_driver.set_permission({name: permissionName}, 'granted');
+
const maxSupportedFrequency = 5;
- sensorProvider.setMaximumSupportedFrequency(maxSupportedFrequency);
+ await test_driver.create_virtual_sensor(
+ testDriverName, {maxSamplingFrequency: maxSupportedFrequency});
+
const sensor = new sensorType({frequency: 50});
- const sensorWatcher = new EventWatcher(t, sensor, ["activate", "error"]);
+ t.add_cleanup(async () => {
+ sensor.stop();
+ await test_driver.remove_virtual_sensor(testDriverName);
+ });
+ const sensorWatcher = new EventWatcher(t, sensor, ['activate', 'error']);
sensor.start();
- const mockSensor = await sensorProvider.getCreatedSensor(sensorName);
-
- await sensorWatcher.wait_for("activate");
+ await sensorWatcher.wait_for('activate');
+ const mockSensorInfo =
+ await test_driver.get_virtual_sensor_information(testDriverName);
- assert_equals(mockSensor.getSamplingFrequency(), maxSupportedFrequency);
- sensor.stop();
- assert_false(sensor.activated);
+ assert_equals(
+ mockSensorInfo.requestedSamplingFrequency, maxSupportedFrequency);
}, `${sensorName}: Test that frequency is capped to the maximum supported\
frequency.`);
- sensor_test(async (t, sensorProvider) => {
- assert_implements(sensorName in self, `${sensorName} is not supported.`);
+ sensor_test(async t => {
+ await test_driver.set_permission({name: permissionName}, 'granted');
+
const minSupportedFrequency = 2;
- sensorProvider.setMinimumSupportedFrequency(minSupportedFrequency);
+ await test_driver.create_virtual_sensor(
+ testDriverName, {minSamplingFrequency: minSupportedFrequency});
+
const sensor = new sensorType({frequency: -1});
- const sensorWatcher = new EventWatcher(t, sensor, ["activate", "error"]);
+ t.add_cleanup(async () => {
+ sensor.stop();
+ await test_driver.remove_virtual_sensor(testDriverName);
+ });
+ const sensorWatcher = new EventWatcher(t, sensor, ['activate', 'error']);
sensor.start();
- const mockSensor = await sensorProvider.getCreatedSensor(sensorName);
-
- await sensorWatcher.wait_for("activate");
+ await sensorWatcher.wait_for('activate');
+ const mockSensorInfo =
+ await test_driver.get_virtual_sensor_information(testDriverName);
- assert_equals(mockSensor.getSamplingFrequency(), minSupportedFrequency);
- sensor.stop();
- assert_false(sensor.activated);
+ assert_equals(
+ mockSensorInfo.requestedSamplingFrequency, minSupportedFrequency);
}, `${sensorName}: Test that frequency is limited to the minimum supported\
frequency.`);
- promise_test(async t => {
- assert_implements(sensorName in self, `${sensorName} is not supported.`);
+ sensor_test(async t => {
const iframe = document.createElement('iframe');
- iframe.allow = featurePolicies.join(' \'none\'; ') + ' \'none\';';
+ iframe.allow = featurePolicyNames.join(' \'none\'; ') + ' \'none\';';
iframe.srcdoc = '<script>' +
- ' window.onmessage = message => {' +
- ' if (message.data === "LOADED") {' +
- ' try {' +
- ' new ' + sensorName + '();' +
- ' parent.postMessage("FAIL", "*");' +
- ' } catch (e) {' +
- ' parent.postMessage("PASS", "*");' +
- ' }' +
- ' }' +
- ' };' +
- '<\/script>';
- const iframeWatcher = new EventWatcher(t, iframe, "load");
+ ' window.onmessage = message => {' +
+ ' if (message.data === "LOADED") {' +
+ ' try {' +
+ ' new ' + sensorName + '();' +
+ ' parent.postMessage("FAIL", "*");' +
+ ' } catch (e) {' +
+ ' parent.postMessage(`PASS: got ${e.name}`, "*");' +
+ ' }' +
+ ' }' +
+ ' };' +
+ '<\/script>';
+ const iframeWatcher = new EventWatcher(t, iframe, 'load');
document.body.appendChild(iframe);
- await iframeWatcher.wait_for("load");
+ await iframeWatcher.wait_for('load');
iframe.contentWindow.postMessage('LOADED', '*');
- const windowWatcher = new EventWatcher(t, window, "message");
- const message = await windowWatcher.wait_for("message");
- assert_equals(message.data, 'PASS');
+ const windowWatcher = new EventWatcher(t, window, 'message');
+ const message = await windowWatcher.wait_for('message');
+ assert_equals(message.data, 'PASS: got SecurityError');
}, `${sensorName}: Test that sensor cannot be constructed within iframe\
disallowed to use feature policy.`);
- promise_test(async t => {
- assert_implements(sensorName in self, `${sensorName} is not supported.`);
+ sensor_test(async t => {
const iframe = document.createElement('iframe');
- iframe.allow = featurePolicies.join(';') + ';';
+ iframe.allow = featurePolicyNames.join(';') + ';';
iframe.srcdoc = '<script>' +
- ' window.onmessage = message => {' +
- ' if (message.data === "LOADED") {' +
- ' try {' +
- ' new ' + sensorName + '();' +
- ' parent.postMessage("PASS", "*");' +
- ' } catch (e) {' +
- ' parent.postMessage("FAIL", "*");' +
- ' }' +
- ' }' +
- ' };' +
- '<\/script>';
- const iframeWatcher = new EventWatcher(t, iframe, "load");
+ ' window.onmessage = message => {' +
+ ' if (message.data === "LOADED") {' +
+ ' try {' +
+ ' new ' + sensorName + '();' +
+ ' parent.postMessage("PASS", "*");' +
+ ' } catch (e) {' +
+ ' parent.postMessage("FAIL", "*");' +
+ ' }' +
+ ' }' +
+ ' };' +
+ '<\/script>';
+ const iframeWatcher = new EventWatcher(t, iframe, 'load');
document.body.appendChild(iframe);
- await iframeWatcher.wait_for("load");
+ await iframeWatcher.wait_for('load');
iframe.contentWindow.postMessage('LOADED', '*');
- const windowWatcher = new EventWatcher(t, window, "message");
- const message = await windowWatcher.wait_for("message");
+ const windowWatcher = new EventWatcher(t, window, 'message');
+ const message = await windowWatcher.wait_for('message');
assert_equals(message.data, 'PASS');
}, `${sensorName}: Test that sensor can be constructed within an iframe\
allowed to use feature policy.`);
- sensor_test(async (t, sensorProvider) => {
- assert_implements(sensorName in self, `${sensorName} is not supported.`);
- const sensor = new sensorType();
- const sensorWatcher = new EventWatcher(t, sensor, ["reading", "error"]);
+ sensor_test(async (t, readings, expectedReadings) => {
+ await test_driver.set_permission({name: permissionName}, 'granted');
+
+ await test_driver.create_virtual_sensor(testDriverName);
+
+ const sensor = new sensorType;
+ t.add_cleanup(async () => {
+ sensor.stop();
+ await test_driver.remove_virtual_sensor(testDriverName);
+ });
+ const sensorWatcher =
+ new EventWatcher(t, sensor, ['activate', 'reading', 'error']);
+
sensor.start();
assert_false(sensor.hasReading);
+ await sensorWatcher.wait_for('activate');
- const mockSensor = await sensorProvider.getCreatedSensor(sensorName);
- mockSensor.setSensorReading(readings);
+ await Promise.all([
+ test_driver.update_virtual_sensor(testDriverName, readings.next().value),
+ sensorWatcher.wait_for('reading')
+ ]);
+
+ assert_sensor_reading_equals(sensor, expectedReadings.next().value);
- await sensorWatcher.wait_for("reading");
- const expected = new RingBuffer(expectedReadings).next().value;
- assert_true(verificationFunction(expected, sensor));
assert_true(sensor.hasReading);
sensor.stop();
- assert_true(verificationFunction(expected, sensor, /*isNull=*/true));
+
+ assert_sensor_reading_is_null(sensor);
assert_false(sensor.hasReading);
}, `${sensorName}: Test that 'onreading' is called and sensor reading is\
valid.`);
- sensor_test(async (t, sensorProvider) => {
- assert_implements(sensorName in self, `${sensorName} is not supported.`);
- const sensor1 = new sensorType();
- const sensorWatcher1 = new EventWatcher(t, sensor1, ["reading", "error"]);
- sensor1.start();
+ sensor_test(async (t, readings, expectedReadings) => {
+ await test_driver.set_permission({name: permissionName}, 'granted');
+ await test_driver.create_virtual_sensor(testDriverName);
+
+ const sensor1 = new sensorType();
const sensor2 = new sensorType();
- const sensorWatcher2 = new EventWatcher(t, sensor2, ["reading", "error"]);
+ t.add_cleanup(async () => {
+ sensor1.stop();
+ sensor2.stop();
+ await test_driver.remove_virtual_sensor(testDriverName);
+ });
+ const sensorWatcher1 =
+ new EventWatcher(t, sensor1, ['activate', 'reading', 'error']);
+ const sensorWatcher2 =
+ new EventWatcher(t, sensor2, ['activate', 'reading', 'error']);
+ sensor1.start();
sensor2.start();
- const mockSensor = await sensorProvider.getCreatedSensor(sensorName);
- mockSensor.setSensorReading(readings);
+ await Promise.all([
+ sensorWatcher1.wait_for('activate'), sensorWatcher2.wait_for('activate')
+ ]);
+
+ await Promise.all([
+ test_driver.update_virtual_sensor(testDriverName, readings.next().value),
+ sensorWatcher1.wait_for('reading'), sensorWatcher2.wait_for('reading')
+ ]);
- await Promise.all([sensorWatcher1.wait_for("reading"),
- sensorWatcher2.wait_for("reading")]);
- const expected = new RingBuffer(expectedReadings).next().value;
// Reading values are correct for both sensors.
- assert_true(verificationFunction(expected, sensor1));
- assert_true(verificationFunction(expected, sensor2));
+ const expected = expectedReadings.next().value;
+ assert_sensor_reading_equals(sensor1, expected);
+ assert_sensor_reading_equals(sensor2, expected);
// After first sensor stops its reading values are null,
// reading values for the second sensor sensor remain.
sensor1.stop();
- assert_true(verificationFunction(expected, sensor1, /*isNull=*/true));
- assert_true(verificationFunction(expected, sensor2));
+ assert_sensor_reading_is_null(sensor1);
+ assert_sensor_reading_equals(sensor2, expected);
sensor2.stop();
- assert_true(verificationFunction(expected, sensor2, /*isNull=*/true));
+ assert_sensor_reading_is_null(sensor2);
}, `${sensorName}: sensor reading is correct.`);
// Tests that readings maps to expectedReadings correctly. Due to threshold
// check and rounding some values might be discarded or changed.
- sensor_test(async (t, sensorProvider) => {
- assert_implements(sensorName in self, `${sensorName} is not supported.`);
+ sensor_test(async (t, readings, expectedReadings) => {
+ await test_driver.set_permission({name: permissionName}, 'granted');
+
+ await test_driver.create_virtual_sensor(testDriverName);
+
const sensor = new sensorType();
- const sensorWatcher = new EventWatcher(t, sensor, ["reading", "error"]);
+ t.add_cleanup(async () => {
+ sensor.stop();
+ await test_driver.remove_virtual_sensor(testDriverName);
+ });
+ const sensorWatcher =
+ new EventWatcher(t, sensor, ['activate', 'reading', 'error']);
sensor.start();
- const mockSensor = await sensorProvider.getCreatedSensor(sensorName);
- await mockSensor.setSensorReading(readings);
+ await sensorWatcher.wait_for('activate');
- for (let expectedReading of expectedReadings) {
- await sensorWatcher.wait_for("reading");
- assert_true(sensor.hasReading, "hasReading");
- assert_true(verificationFunction(expectedReading, sensor),
- "verification");
- }
+ const sensorInfo =
+ await test_driver.get_virtual_sensor_information(testDriverName);
+ const sensorPeriodInMs = (1 / sensorInfo.requestedSamplingFrequency) * 1000;
- sensor.stop();
+ for (let expectedReading of expectedReadings.data) {
+ await update_virtual_sensor_until_reading(
+ t, readings, sensorWatcher.wait_for('reading'), testDriverName,
+ sensorPeriodInMs * 3);
+ assert_true(sensor.hasReading, 'hasReading');
+ assert_sensor_reading_equals(sensor, expectedReading);
+ }
}, `${sensorName}: Test that readings are all mapped to expectedReadings\
correctly.`);
- sensor_test(async (t, sensorProvider) => {
- assert_implements(sensorName in self, `${sensorName} is not supported.`);
+ sensor_test(async (t, readings) => {
+ await test_driver.set_permission({name: permissionName}, 'granted');
+
+ await test_driver.create_virtual_sensor(testDriverName);
+
const sensor = new sensorType();
- const sensorWatcher = new EventWatcher(t, sensor, ["reading", "error"]);
+ t.add_cleanup(async () => {
+ sensor.stop();
+ await test_driver.remove_virtual_sensor(testDriverName);
+ });
+ const sensorWatcher =
+ new EventWatcher(t, sensor, ['activate', 'reading', 'error']);
sensor.start();
- const mockSensor = await sensorProvider.getCreatedSensor(sensorName);
- mockSensor.setSensorReading(readings);
+ await sensorWatcher.wait_for('activate');
- await sensorWatcher.wait_for("reading");
+ const sensorInfo =
+ await test_driver.get_virtual_sensor_information(testDriverName);
+ const sensorPeriodInMs = (1 / sensorInfo.requestedSamplingFrequency) * 1000;
+
+ await Promise.all([
+ test_driver.update_virtual_sensor(testDriverName, readings.next().value),
+ sensorWatcher.wait_for('reading')
+ ]);
const cachedTimeStamp1 = sensor.timestamp;
- await sensorWatcher.wait_for("reading");
+ await update_virtual_sensor_until_reading(
+ t, readings, sensorWatcher.wait_for('reading'), testDriverName,
+ sensorPeriodInMs * 3);
const cachedTimeStamp2 = sensor.timestamp;
assert_greater_than(cachedTimeStamp2, cachedTimeStamp1);
- sensor.stop();
}, `${sensorName}: sensor timestamp is updated when time passes.`);
sensor_test(async t => {
- assert_implements(sensorName in self, `${sensorName} is not supported.`);
+ await test_driver.set_permission({name: permissionName}, 'granted');
+
+ await test_driver.create_virtual_sensor(testDriverName);
+
const sensor = new sensorType();
- const sensorWatcher = new EventWatcher(t, sensor, ["activate", "error"]);
+ t.add_cleanup(async () => {
+ sensor.stop();
+ await test_driver.remove_virtual_sensor(testDriverName);
+ });
+ const sensorWatcher = new EventWatcher(t, sensor, ['activate', 'error']);
assert_false(sensor.activated);
sensor.start();
assert_false(sensor.activated);
- await sensorWatcher.wait_for("activate");
+ await sensorWatcher.wait_for('activate');
assert_true(sensor.activated);
sensor.stop();
@@ -305,245 +360,331 @@ function runGenericSensorTests(sensorName,
states are correct.`);
sensor_test(async t => {
- assert_implements(sensorName in self, `${sensorName} is not supported.`);
+ await test_driver.set_permission({name: permissionName}, 'granted');
+
+ await test_driver.create_virtual_sensor(testDriverName);
+
const sensor = new sensorType();
- const sensorWatcher = new EventWatcher(t, sensor, ["activate", "error"]);
+ t.add_cleanup(async () => {
+ sensor.stop();
+ await test_driver.remove_virtual_sensor(testDriverName);
+ });
+ const sensorWatcher = new EventWatcher(t, sensor, ['activate', 'error']);
sensor.start();
sensor.start();
- await sensorWatcher.wait_for("activate");
+ await sensorWatcher.wait_for('activate');
assert_true(sensor.activated);
- sensor.stop();
}, `${sensorName}: no exception is thrown when calling start() on already\
started sensor.`);
sensor_test(async t => {
- assert_implements(sensorName in self, `${sensorName} is not supported.`);
+ await test_driver.set_permission({name: permissionName}, 'granted');
+
+ await test_driver.create_virtual_sensor(testDriverName);
+
const sensor = new sensorType();
- const sensorWatcher = new EventWatcher(t, sensor, ["activate", "error"]);
+ t.add_cleanup(async () => {
+ sensor.stop();
+ await test_driver.remove_virtual_sensor(testDriverName);
+ });
+ const sensorWatcher = new EventWatcher(t, sensor, ['activate', 'error']);
sensor.start();
- await sensorWatcher.wait_for("activate");
+ await sensorWatcher.wait_for('activate');
sensor.stop();
sensor.stop();
assert_false(sensor.activated);
}, `${sensorName}: no exception is thrown when calling stop() on already\
stopped sensor.`);
- sensor_test(async (t, sensorProvider) => {
- assert_implements(sensorName in self, `${sensorName} is not supported.`);
+ sensor_test(async (t, readings, expectedReadings) => {
+ await test_driver.set_permission({name: permissionName}, 'granted');
+
+ await test_driver.create_virtual_sensor(testDriverName);
+
const sensor = new sensorType();
- const sensorWatcher = new EventWatcher(t, sensor, ["reading", "error"]);
+ t.add_cleanup(async () => {
+ sensor.stop();
+ await test_driver.remove_virtual_sensor(testDriverName);
+ });
+ const sensorWatcher =
+ new EventWatcher(t, sensor, ['activate', 'reading', 'error']);
sensor.start();
- const mockSensor = await sensorProvider.getCreatedSensor(sensorName);
- mockSensor.setSensorReading(readings);
+ await sensorWatcher.wait_for('activate');
+
+ await Promise.all([
+ test_driver.update_virtual_sensor(testDriverName, readings.next().value),
+ sensorWatcher.wait_for('reading')
+ ]);
- const expectedBuffer = new RingBuffer(expectedReadings);
- await sensorWatcher.wait_for("reading");
- const expected1 = expectedBuffer.next().value;
assert_true(sensor.hasReading);
- assert_true(verificationFunction(expected1, sensor));
+
+ const expected = expectedReadings.next().value;
+ assert_sensor_reading_equals(sensor, expected);
+
const timestamp = sensor.timestamp;
sensor.stop();
assert_false(sensor.hasReading);
+ assert_false(sensor.activated);
sensor.start();
- await sensorWatcher.wait_for("reading");
+
+ await sensorWatcher.wait_for('activate');
+ assert_false(sensor.hasReading);
+ readings.reset();
+ await Promise.all([
+ test_driver.update_virtual_sensor(testDriverName, readings.next().value),
+ sensorWatcher.wait_for('reading')
+ ]);
assert_true(sensor.hasReading);
- // |readingData| may have a single reading/expectation value, and this
- // is the second reading we are getting. For that case, make sure we
- // also wrap around as if we had the same RingBuffer used in
- // generic_sensor_mocks.js.
- const expected2 = expectedBuffer.next().value;
- assert_true(verificationFunction(expected2, sensor));
+
+ assert_sensor_reading_equals(sensor, expected);
// Make sure that 'timestamp' is already initialized.
assert_greater_than(timestamp, 0);
// Check that the reading is updated.
assert_greater_than(sensor.timestamp, timestamp);
- sensor.stop();
}, `${sensorName}: Test that fresh reading is fetched on start().`);
- sensor_test(async (t, sensorProvider) => {
- assert_implements(sensorName in self, `${sensorName} is not supported.`);
+ sensor_test(async (t, readings, expectedReadings) => {
+ await test_driver.set_permission({name: permissionName}, 'granted');
+
+ await test_driver.create_virtual_sensor(testDriverName);
+
const sensor = new sensorType();
- t.add_cleanup(() => {
+ t.add_cleanup(async () => {
sensor.stop();
+ await test_driver.remove_virtual_sensor(testDriverName);
});
- const sensorWatcher = new EventWatcher(t, sensor, ['reading', 'error']);
- sensor.start();
+ const sensorWatcher =
+ new EventWatcher(t, sensor, ['activate', 'reading', 'error']);
- const mockSensor = await sensorProvider.getCreatedSensor(sensorName);
- mockSensor.setSensorReading(readings);
+ sensor.start();
+ await sensorWatcher.wait_for('activate');
- const expectedBuffer = new RingBuffer(expectedReadings);
- await sensorWatcher.wait_for('reading');
- const expected1 = expectedBuffer.next().value;
- assert_true(verificationFunction(expected1, sensor));
- assert_true(mockSensor.isReadingData());
- const cachedTimestamp1 = sensor.timestamp;
+ assert_false(sensor.hasReading);
+ assert_sensor_reading_is_null(sensor);
const {minimize, restore} = window_state_context(t);
await minimize();
assert_true(document.hidden);
- await t.step_wait(
- () => !mockSensor.isReadingData(), 'readings must be suspended');
- const cachedTimestamp2 = sensor.timestamp;
- assert_equals(cachedTimestamp1, cachedTimestamp2);
+ assert_true(sensor.activated);
+ assert_false(sensor.hasReading);
+ assert_sensor_reading_is_null(sensor);
+
+ const reading = readings.next().value;
+ await test_driver.update_virtual_sensor(testDriverName, reading);
await restore();
assert_false(document.hidden);
- await t.step_wait(
- () => mockSensor.isReadingData(), 'readings must be restored');
- await sensorWatcher.wait_for('reading');
- const expected2 = expectedBuffer.next().value;
- assert_true(verificationFunction(expected2, sensor));
- assert_greater_than(sensor.timestamp, cachedTimestamp2);
- }, `${sensorName}: Losing visibility must cause readings to be suspended.`);
-
- sensor_test(async (t, sensorProvider) => {
- assert_implements(sensorName in self, `${sensorName} is not supported.`);
-
- const fastSensor = new sensorType({ frequency: 60 });
- t.add_cleanup(() => { fastSensor.stop(); });
- let eventWatcher = new EventWatcher(t, fastSensor, "activate");
+ assert_true(sensor.activated);
+ assert_false(sensor.hasReading);
+ assert_sensor_reading_is_null(sensor);
+
+ const visiblePageTimestamp = performance.now();
+
+ const [readingEvent] = await Promise.all([
+ sensorWatcher.wait_for('reading'),
+ test_driver.update_virtual_sensor(testDriverName, reading),
+ ]);
+
+ const postReadingTimestamp = performance.now();
+
+ assert_sensor_reading_equals(sensor, expectedReadings.next().value);
+
+ // Check that the only reading we received all this time was the one sent
+ // after the page was made visible again. This is done by verifying the
+ // timestamps of the event as well as the current reading's.
+ assert_greater_than_equal(sensor.timestamp, visiblePageTimestamp);
+ assert_greater_than(readingEvent.timeStamp, sensor.timestamp);
+ assert_greater_than_equal(
+ postReadingTimestamp, readingEvent.timeStamp,
+ 'No new reading events have been delivered');
+ }, `${sensorName}: Readings are not delivered when the page has no visibility`);
+
+ sensor_test(async t => {
+ await test_driver.set_permission({name: permissionName}, 'granted');
+
+ await test_driver.create_virtual_sensor(testDriverName);
+
+ const fastSensor = new sensorType({frequency: 60});
+ t.add_cleanup(() => {
+ fastSensor.stop();
+ });
+ let eventWatcher = new EventWatcher(t, fastSensor, ['activate']);
fastSensor.start();
// Wait for |fastSensor| to be activated so that the call to
// getSamplingFrequency() below works.
- await eventWatcher.wait_for("activate");
+ await eventWatcher.wait_for('activate');
- const mockSensor = await sensorProvider.getCreatedSensor(sensorName);
- mockSensor.setSensorReading(readings);
+ let mockSensorInfo =
+ await test_driver.get_virtual_sensor_information(testDriverName);
// We need |fastSensorFrequency| because 60Hz might be higher than a sensor
// type's maximum allowed frequency.
- const fastSensorFrequency = mockSensor.getSamplingFrequency();
+ const fastSensorFrequency = mockSensorInfo.requestedSamplingFrequency;
const slowSensorFrequency = fastSensorFrequency * 0.25;
- const slowSensor = new sensorType({ frequency: slowSensorFrequency });
- t.add_cleanup(() => { slowSensor.stop(); });
- eventWatcher = new EventWatcher(t, slowSensor, "activate");
+ const slowSensor = new sensorType({frequency: slowSensorFrequency});
+ t.add_cleanup(() => {
+ slowSensor.stop();
+ });
+ t.add_cleanup(async () => {
+ // Remove the virtual sensor only after calling stop() on both sensors.
+ await test_driver.remove_virtual_sensor(testDriverName);
+ });
+ eventWatcher = new EventWatcher(t, slowSensor, 'activate');
slowSensor.start();
// Wait for |slowSensor| to be activated before we check if the mock
// platform sensor's sampling frequency has changed.
- await eventWatcher.wait_for("activate");
- assert_equals(mockSensor.getSamplingFrequency(), fastSensorFrequency);
+ await eventWatcher.wait_for('activate');
+ mockSensorInfo =
+ await test_driver.get_virtual_sensor_information(testDriverName);
+ assert_equals(
+ mockSensorInfo.requestedSamplingFrequency, fastSensorFrequency);
// Now stop |fastSensor| and verify that the sampling frequency has dropped
// to the one |slowSensor| had requested.
fastSensor.stop();
- return t.step_wait(() => {
- return mockSensor.getSamplingFrequency() === slowSensorFrequency;
- }, "Sampling frequency has dropped to slowSensor's requested frequency");
+ await wait_for_virtual_sensor_state(testDriverName, (info) => {
+ return info.requestedSamplingFrequency === slowSensorFrequency;
+ });
}, `${sensorName}: frequency hint works.`);
- sensor_test(async (t, sensorProvider) => {
- assert_implements(sensorName in self, `${sensorName} is not supported.`);
+ sensor_test(async (t, readings, expectedReadings) => {
+ await test_driver.set_permission({name: permissionName}, 'granted');
+
+ await test_driver.create_virtual_sensor(testDriverName);
const sensor1 = new sensorType();
const sensor2 = new sensorType();
- return new Promise((resolve, reject) => {
+ t.add_cleanup(async () => {
+ sensor1.stop();
+ sensor2.stop();
+ await test_driver.remove_virtual_sensor(testDriverName);
+ });
+
+ return new Promise(async (resolve, reject) => {
sensor1.addEventListener('reading', () => {
sensor2.addEventListener('activate', () => {
try {
assert_true(sensor1.activated);
assert_true(sensor1.hasReading);
- assert_false(verificationFunction(null, sensor1, /*isNull=*/true));
- assert_not_equals(sensor1.timestamp, null);
+
+ const expected = expectedReadings.next().value;
+ assert_sensor_reading_equals(sensor1, expected);
assert_true(sensor2.activated);
- assert_false(verificationFunction(null, sensor2, /*isNull=*/true));
- assert_not_equals(sensor2.timestamp, null);
+ assert_sensor_reading_equals(sensor2, expected);
} catch (e) {
reject(e);
}
- }, { once: true });
+ }, {once: true});
sensor2.addEventListener('reading', () => {
try {
assert_true(sensor2.activated);
assert_true(sensor2.hasReading);
- assert_sensor_equals(sensor1, sensor2);
+ assert_sensor_reading_equals(sensor1, sensor2);
+ assert_equals(sensor1.timestamp, sensor2.timestamp);
resolve();
} catch (e) {
reject(e);
}
- }, { once: true });
+ }, {once: true});
sensor2.start();
- }, { once: true });
+ }, {once: true});
+
+ const eventWatcher = new EventWatcher(t, sensor1, ['activate']);
sensor1.start();
+ await eventWatcher.wait_for('activate');
+ test_driver.update_virtual_sensor(testDriverName, readings.next().value);
});
}, `${sensorName}: Readings delivered by shared platform sensor are\
immediately accessible to all sensors.`);
-// Re-enable after https://github.com/w3c/sensors/issues/361 is fixed.
-// test(() => {
-// assert_throws_dom("NotSupportedError",
-// () => { new sensorType({invalid: 1}) });
-// assert_throws_dom("NotSupportedError",
-// () => { new sensorType({frequency: 60, invalid: 1}) });
-// if (!expectedRemappedReadings) {
-// assert_throws_dom("NotSupportedError",
-// () => { new sensorType({referenceFrame: "screen"}) });
-// }
-// }, `${sensorName}: throw 'NotSupportedError' for an unsupported sensor\
-// option.`);
+ // Re-enable after https://github.com/w3c/sensors/issues/361 is fixed.
+ // test(() => {
+ // assert_throws_dom("NotSupportedError",
+ // () => { new sensorType({invalid: 1}) });
+ // assert_throws_dom("NotSupportedError",
+ // () => { new sensorType({frequency: 60, invalid: 1}) });
+ // if (!expectedRemappedReadings) {
+ // assert_throws_dom("NotSupportedError",
+ // () => { new sensorType({referenceFrame: "screen"}) });
+ // }
+ // }, `${sensorName}: throw 'NotSupportedError' for an unsupported sensor\
+ // option.`);
test(() => {
- assert_implements(sensorName in self, `${sensorName} is not supported.`);
- const invalidFreqs = [
- "invalid",
- NaN,
- Infinity,
- -Infinity,
- {}
- ];
+ const invalidFreqs = ['invalid', NaN, Infinity, -Infinity, {}];
invalidFreqs.map(freq => {
- assert_throws_js(TypeError,
- () => { new sensorType({frequency: freq}) },
- `when freq is ${freq}`);
+ assert_throws_js(
+ TypeError, () => {new sensorType({frequency: freq})},
+ `when freq is ${freq}`);
});
}, `${sensorName}: throw 'TypeError' if frequency is invalid.`);
- if (!expectedRemappedReadings) {
+ if (!readingData.expectedRemappedReadings) {
// The sensorType does not represent a spatial sensor.
return;
}
- sensor_test(async (t, sensorProvider) => {
- assert_implements(sensorName in self, `${sensorName} is not supported.`);
- const sensor1 = new sensorType({frequency: 60});
- const sensor2 = new sensorType({frequency: 60, referenceFrame: "screen"});
- const sensorWatcher1 = new EventWatcher(t, sensor1, ["reading", "error"]);
- const sensorWatcher2 = new EventWatcher(t, sensor1, ["reading", "error"]);
-
- sensor1.start();
- sensor2.start();
-
- const mockSensor = await sensorProvider.getCreatedSensor(sensorName);
- mockSensor.setSensorReading(readings);
-
- await Promise.all([sensorWatcher1.wait_for("reading"),
- sensorWatcher2.wait_for("reading")]);
-
- const expected = new RingBuffer(expectedReadings).next().value;
- const expectedRemapped =
- new RingBuffer(expectedRemappedReadings).next().value;
- assert_true(verificationFunction(expected, sensor1));
- assert_true(verificationFunction(expectedRemapped, sensor2));
-
- sensor1.stop();
- assert_true(verificationFunction(expected, sensor1, /*isNull=*/true));
- assert_true(verificationFunction(expectedRemapped, sensor2));
-
- sensor2.stop();
- assert_true(verificationFunction(expectedRemapped, sensor2,
- /*isNull=*/true));
- }, `${sensorName}: sensor reading is correct when options.referenceFrame\
- is 'screen'.`);
+ // TODO(https://github.com/web-platform-tests/wpt/issues/42724): Re-enable
+ // when there is a cross-platform way to set an orientation angle.
+ // sensor_test(
+ // async (t, readings, expectedReadings, expectedRemappedReadings) => {
+ // assert_implements_optional(screen.orientation.angle == 270,
+ // 'Remapped values expect a specific screen rotation.');
+ // await test_driver.set_permission({name: permissionName}, 'granted');
+
+ // await test_driver.create_virtual_sensor(testDriverName);
+
+ // const sensor1 = new sensorType({frequency: 60});
+ // const sensor2 =
+ // new sensorType({frequency: 60, referenceFrame: 'screen'});
+ // t.add_cleanup(async () => {
+ // sensor1.stop();
+ // sensor2.stop();
+ // await test_driver.remove_virtual_sensor(testDriverName);
+ // });
+ // const sensorWatcher1 =
+ // new EventWatcher(t, sensor1, ['activate', 'reading', 'error']);
+ // const sensorWatcher2 =
+ // new EventWatcher(t, sensor1, ['activate', 'reading', 'error']);
+
+ // sensor1.start();
+ // sensor2.start();
+
+ // await Promise.all([
+ // sensorWatcher1.wait_for('activate'),
+ // sensorWatcher2.wait_for('activate')
+ // ]);
+
+ // await Promise.all([
+ // test_driver.update_virtual_sensor(testDriverName,
+ // readings.next().value), sensorWatcher1.wait_for('reading'),
+ // sensorWatcher2.wait_for('reading')
+ // ]);
+
+ // const expected = expectedReadings.next().value;
+ // const expectedRemapped = expectedRemappedReadings.next().value;
+ // assert_sensor_reading_equals(sensor1, expected);
+ // assert_sensor_reading_equals(sensor2, expectedRemapped);
+
+ // sensor1.stop();
+ // assert_sensor_reading_is_null(sensor1);
+ // assert_sensor_reading_equals(sensor2, expectedRemapped);
+
+ // sensor2.stop();
+ // assert_sensor_reading_is_null(sensor2);
+ // },
+ // `${sensorName}: sensor reading is correct when options.referenceFrame\
+ // is 'screen'.`);
}
function runGenericSensorInsecureContext(sensorName) {
diff --git a/tests/wpt/tests/generic-sensor/resources/generic-sensor-helpers.js b/tests/wpt/tests/generic-sensor/resources/generic-sensor-helpers.js
index 9a51a591ce1..146f4292ade 100644
--- a/tests/wpt/tests/generic-sensor/resources/generic-sensor-helpers.js
+++ b/tests/wpt/tests/generic-sensor/resources/generic-sensor-helpers.js
@@ -1,142 +1,179 @@
'use strict';
-// These tests rely on the User Agent providing an implementation of
-// platform sensor backends.
-//
-// In Chromium-based browsers this implementation is provided by a polyfill
-// in order to reduce the amount of test-only code shipped to users. To enable
-// these tests the browser must be run with these options:
-//
-// --enable-blink-features=MojoJS,MojoJSTest
-async function loadChromiumResources() {
- await loadScript('/resources/testdriver.js');
- await loadScript('/resources/testdriver-vendor.js');
- await loadScript('/page-visibility/resources/window_state_context.js');
- await import('/resources/chromium/generic_sensor_mocks.js');
-}
-
-async function initialize_generic_sensor_tests() {
- if (typeof GenericSensorTest === 'undefined') {
- const script = document.createElement('script');
- script.src = '/resources/test-only-api.js';
- script.async = false;
- const p = new Promise((resolve, reject) => {
- script.onload = () => { resolve(); };
- script.onerror = e => { reject(e); };
- })
- document.head.appendChild(script);
- await p;
-
- if (isChromiumBased) {
- await loadChromiumResources();
+// If two doubles differ by less than this amount, we can consider them
+// to be effectively equal.
+const kEpsilon = 1e-8;
+
+class RingBuffer {
+ constructor(data) {
+ if (!Array.isArray(data)) {
+ throw new TypeError('`data` must be an array.');
}
+
+ this.bufferPosition_ = 0;
+ this.data_ = Array.from(data);
}
- let sensorTest = new GenericSensorTest();
- await sensorTest.initialize();
- return sensorTest;
-}
+ get data() {
+ return Array.from(this.data_);
+ }
-function sensor_test(func, name, properties) {
- promise_test(async (t) => {
- t.add_cleanup(() => {
- if (sensorTest)
- return sensorTest.reset();
- });
+ next() {
+ const value = this.data_[this.bufferPosition_];
+ this.bufferPosition_ = (this.bufferPosition_ + 1) % this.data_.length;
+ return {done: false, value: value};
+ }
- let sensorTest = await initialize_generic_sensor_tests();
- return func(t, sensorTest.getSensorProvider());
- }, name, properties);
-}
+ value() {
+ return this.data_[this.bufferPosition_];
+ }
-function verifySensorReading(pattern, values, timestamp, isNull) {
- // If |val| cannot be converted to a float, we return the original value.
- // This can happen when a value in |pattern| is not a number.
- function round(val) {
- const res = Number.parseFloat(val).toPrecision(6);
- return res === "NaN" ? val : res;
+ [Symbol.iterator]() {
+ return this;
}
- if (isNull) {
- return (values === null || values.every(r => r === null)) &&
- timestamp === null;
+ reset() {
+ this.bufferPosition_ = 0;
+ }
+};
+
+// Calls test_driver.update_virtual_sensor() until it results in a "reading"
+// event. It waits |timeoutInMs| before considering that an event has not been
+// delivered.
+async function update_virtual_sensor_until_reading(
+ t, readings, readingPromise, testDriverName, timeoutInMs) {
+ while (true) {
+ await test_driver.update_virtual_sensor(
+ testDriverName, readings.next().value);
+ const value = await Promise.race([
+ new Promise(
+ resolve => {t.step_timeout(() => resolve('TIMEOUT'), timeoutInMs)}),
+ readingPromise,
+ ]);
+ if (value !== 'TIMEOUT') {
+ break;
+ }
}
+}
- return values.every((r, i) => round(r) === round(pattern[i])) &&
- timestamp !== null;
+// This could be turned into a t.step_wait() call once
+// https://github.com/web-platform-tests/wpt/pull/34289 is merged.
+async function wait_for_virtual_sensor_state(testDriverName, predicate) {
+ const result =
+ await test_driver.get_virtual_sensor_information(testDriverName);
+ if (!predicate(result)) {
+ await wait_for_virtual_sensor_state(testDriverName, predicate);
+ }
}
-function verifyXyzSensorReading(pattern, {x, y, z, timestamp}, isNull) {
- return verifySensorReading(pattern, [x, y, z], timestamp, isNull);
+function validate_sensor_data(sensorData) {
+ if (!('sensorName' in sensorData)) {
+ throw new TypeError('sensorData.sensorName is missing');
+ }
+ if (!('permissionName' in sensorData)) {
+ throw new TypeError('sensorData.permissionName is missing');
+ }
+ if (!('testDriverName' in sensorData)) {
+ throw new TypeError('sensorData.testDriverName is missing');
+ }
+ if (sensorData.featurePolicyNames !== undefined &&
+ !Array.isArray(sensorData.featurePolicyNames)) {
+ throw new TypeError('sensorData.featurePolicyNames must be an array');
+ }
}
-function verifyQuatSensorReading(pattern, {quaternion, timestamp}, isNull) {
- return verifySensorReading(pattern, quaternion, timestamp, isNull);
+function validate_reading_data(readingData) {
+ if (!Array.isArray(readingData.readings)) {
+ throw new TypeError('readingData.readings must be an array.');
+ }
+ if (!Array.isArray(readingData.expectedReadings)) {
+ throw new TypeError('readingData.expectedReadings must be an array.');
+ }
+ if (readingData.readings.length < readingData.expectedReadings.length) {
+ throw new TypeError(
+ 'readingData.readings\' length must be bigger than ' +
+ 'or equal to readingData.expectedReadings\' length.');
+ }
+ if (readingData.expectedRemappedReadings &&
+ !Array.isArray(readingData.expectedRemappedReadings)) {
+ throw new TypeError(
+ 'readingData.expectedRemappedReadings must be an ' +
+ 'array.');
+ }
+ if (readingData.expectedRemappedReadings &&
+ readingData.expectedReadings.length !=
+ readingData.expectedRemappedReadings.length) {
+ throw new TypeError(
+ 'readingData.expectedReadings and ' +
+ 'readingData.expectedRemappedReadings must have the same ' +
+ 'length.');
+ }
}
-function verifyAlsSensorReading(pattern, {illuminance, timestamp}, isNull) {
- return verifySensorReading(pattern, [illuminance], timestamp, isNull);
+function get_sensor_reading_properties(sensor) {
+ const className = sensor[Symbol.toStringTag];
+ if ([
+ 'Accelerometer', 'GravitySensor', 'Gyroscope',
+ 'LinearAccelerationSensor', 'Magnetometer', 'ProximitySensor'
+ ].includes(className)) {
+ return ['x', 'y', 'z'];
+ } else if (className == 'AmbientLightSensor') {
+ return ['illuminance'];
+ } else if ([
+ 'AbsoluteOrientationSensor', 'RelativeOrientationSensor'
+ ].includes(className)) {
+ return ['quaternion'];
+ } else {
+ throw new TypeError(`Unexpected sensor '${className}'`);
+ }
}
-function verifyGeoSensorReading(pattern, {latitude, longitude, altitude,
- accuracy, altitudeAccuracy, heading, speed, timestamp}, isNull) {
- return verifySensorReading(pattern, [latitude, longitude, altitude,
- accuracy, altitudeAccuracy, heading, speed], timestamp, isNull);
+// Checks that `sensor` and `expectedSensorLike` have the same properties
+// (except for timestamp) and they have the same values.
+//
+// Options allows configuring some aspects of the comparison:
+// - ignoreTimestamps (boolean): If true, `sensor` and `expectedSensorLike`'s
+// "timestamp" attribute will not be compared. If `expectedSensorLike` does
+// not have a "timestamp" attribute, the values will not be compared either.
+// This is particularly useful when comparing sensor objects from different
+// origins (and consequently different time origins).
+function assert_sensor_reading_equals(
+ sensor, expectedSensorLike, options = {}) {
+ for (const prop of get_sensor_reading_properties(sensor)) {
+ assert_true(
+ prop in expectedSensorLike,
+ `expectedSensorLike must have a property called '${prop}'`);
+ if (Array.isArray(sensor[prop]))
+ assert_array_approx_equals(
+ sensor[prop], expectedSensorLike[prop], kEpsilon);
+ else
+ assert_approx_equals(sensor[prop], expectedSensorLike[prop], kEpsilon);
+ }
+ assert_not_equals(sensor.timestamp, null);
+
+ if ('timestamp' in expectedSensorLike && !options.ignoreTimestamps) {
+ assert_equals(
+ sensor.timestamp, expectedSensorLike.timestamp,
+ 'Sensor timestamps must be equal');
+ }
}
-function verifyProximitySensorReading(pattern, {distance, max, near, timestamp}, isNull) {
- return verifySensorReading(pattern, [distance, max, near], timestamp, isNull);
+function assert_sensor_reading_is_null(sensor) {
+ for (const prop of get_sensor_reading_properties(sensor)) {
+ assert_equals(sensor[prop], null);
+ }
+ assert_equals(sensor.timestamp, null);
}
-// Assert that two Sensor objects have the same properties and values.
-//
-// Verifies that ``actual`` and ``expected`` have the same sensor properties
-// and, if so, that their values are the same.
-//
-// @param {Sensor} actual - Test value.
-// @param {Sensor} expected - Expected value.
-function assert_sensor_equals(actual, expected) {
- assert_true(
- actual instanceof Sensor,
- 'assert_sensor_equals: actual must be a Sensor');
- assert_true(
- expected instanceof Sensor,
- 'assert_sensor_equals: expected must be a Sensor');
-
- // These properties vary per sensor type.
- const CUSTOM_PROPERTIES = [
- ['illuminance'], ['quaternion'], ['x', 'y', 'z'],
- [
- 'latitude', 'longitude', 'altitude', 'accuracy', 'altitudeAccuracy',
- 'heading', 'speed'
- ]
- ];
-
- // These properties are present on all objects derived from Sensor.
- const GENERAL_PROPERTIES = ['timestamp'];
-
- for (let customProperties of CUSTOM_PROPERTIES) {
- if (customProperties.every(p => p in actual) &&
- customProperties.every(p => p in expected)) {
- customProperties.forEach(p => {
- if (customProperties == 'quaternion') {
- assert_array_equals(
- actual[p], expected[p],
- `assert_sensor_equals: property '${p}' does not match`);
- } else {
- assert_equals(
- actual[p], expected[p],
- `assert_sensor_equals: property '${p}' does not match`);
- }
- });
- GENERAL_PROPERTIES.forEach(p => {
- assert_equals(
- actual[p], expected[p],
- `assert_sensor_equals: property '${p}' does not match`);
- });
- return;
- }
+function serialize_sensor_data(sensor) {
+ const sensorData = {};
+ for (const property of get_sensor_reading_properties(sensor)) {
+ sensorData[property] = sensor[property];
}
+ sensorData['timestamp'] = sensor.timestamp;
+
+ // Note that this is not serialized by postMessage().
+ sensorData[Symbol.toStringTag] = sensor[Symbol.toStringTag];
- assert_true(false, 'assert_sensor_equals: sensors have different attributes');
+ return sensorData;
}
diff --git a/tests/wpt/tests/generic-sensor/resources/iframe_sensor_handler.html b/tests/wpt/tests/generic-sensor/resources/iframe_sensor_handler.html
index 4528c57a6be..80cdcf7c0d0 100644
--- a/tests/wpt/tests/generic-sensor/resources/iframe_sensor_handler.html
+++ b/tests/wpt/tests/generic-sensor/resources/iframe_sensor_handler.html
@@ -1,63 +1,91 @@
<!DOCTYPE html>
<meta charset="utf-8">
-<title>iframe sensor tester</title>
+<title>cross-origin iframe sensor tester</title>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
<script src="/generic-sensor/resources/generic-sensor-helpers.js"></script>
<script>
- let mockBackend = null;
let sensor = null;
- let sensorType = null;
+
+ test_driver.set_test_context(window.parent);
+
+ // This function is defined separately so that it is added only once
+ // regardless of how many times the 'start_sensor' command is received.
+ function sensorReadingEventHandler() {
+ window.parent.postMessage(
+ {
+ eventName: 'reading',
+ serializedSensor: serialize_sensor_data(sensor),
+ }, '*');
+ }
async function messageHandler(e) {
- if (e.data.command === 'create_sensor') {
- if (!sensor) {
- mockBackend = await initialize_generic_sensor_tests();
- sensor = new self[e.data.type]();
- sensorType = e.data.type;
- }
-
- return Promise.resolve('success');
- } else if (e.data.command === 'start_sensor') {
- if (!sensor) {
- return Promise.reject('"create_sensor" must be called first');
- }
-
- return new Promise((resolve, reject) => {
- sensor.addEventListener('reading', () => {
- resolve('success');
- }, { once: true });
- sensor.addEventListener('error', e => {
- reject(`${e.error.name}: ${e.error.message}`);
- }, { once: true });
- sensor.start();
- });
- } else if (e.data.command === 'is_sensor_suspended') {
- if (!mockBackend) {
- return Promise.reject('"create_sensor" must be called first');
- }
-
- const mockPlatformSensor = await mockBackend.getSensorProvider().getCreatedSensor(sensorType);
- return Promise.resolve(!mockPlatformSensor.isReadingData());
- } else if (e.data.command === 'reset_sensor_backend') {
- if (sensor) {
- sensor.stop();
- await mockBackend.reset();
-
- sensor = null;
- mockBackend = null;
- }
- return Promise.resolve('success');
- } else {
- return Promise.reject(`unknown command "${e.data.command}"`);
+ switch (e.data.command) {
+ case 'create_sensor':
+ if (!sensor) {
+ const { sensorName, permissionName } = e.data.sensorData;
+ // TODO(https://github.com/w3c/permissions/issues/419): This does not
+ // work as expected: due to the set_test_context() call above, this
+ // call goes through the top-level frame, which has a different
+ // origin in cross-origin tests, meaning that cross-origin tests only
+ // really work when permissions are granted by default. This can only
+ // be fixed by testdriver.js allowing set_permission() to specify a
+ // different origin.
+ await test_driver.set_permission({ name: permissionName }, 'granted');
+ sensor = new self[sensorName]();
+ }
+ return Promise.resolve();
+
+ case 'start_sensor':
+ return new Promise((resolve, reject) => {
+ // This event listener is different from the ones below, as it is
+ // supposed to be used together with IframeSensorReadingEventWatcher.
+ // It sends a message whenever there is an event, and window.parent
+ // decides whether it was expected or not. It is the only way to have
+ // something akin to EventWatcher in a cross-origin iframe.
+ sensor.addEventListener('reading', sensorReadingEventHandler);
+
+ sensor.addEventListener('activate', () => {
+ resolve();
+ }, { once: true });
+ sensor.addEventListener('error', e => {
+ reject(`${e.error.name}: ${e.error.message}`);
+ }, { once: true });
+ sensor.start();
+ });
+
+ case 'has_reading':
+ return Promise.resolve(sensor.hasReading);
+
+ case 'stop_sensor':
+ if (sensor) {
+ sensor.stop();
+ }
+ return Promise.resolve();
+
+ default:
+ return Promise.reject(`unknown command "${e.data.command}"`);
}
}
window.onmessage = async (e) => {
- let reply;
+ // The call to test_driver.set_context() above makes messages other than
+ // those we are specifically waiting for to be delivered too. Ignore those
+ // here.
+ if (!e.data.command) {
+ return;
+ }
+
try {
- reply = await messageHandler(e);
+ test_driver.message_test({
+ command: e.data.command,
+ result: await messageHandler(e),
+ });
} catch (error) {
- reply = error;
+ test_driver.message_test({
+ command: e.data.command,
+ error,
+ });
}
- e.source.postMessage({ command: e.data.command, result: reply }, '*');
}
</script>
diff --git a/tests/wpt/tests/geolocation-sensor/GeolocationSensor-iframe-access.https.html b/tests/wpt/tests/geolocation-sensor/GeolocationSensor-iframe-access.https.html
index bb0541de32c..a3d39e3606f 100644
--- a/tests/wpt/tests/geolocation-sensor/GeolocationSensor-iframe-access.https.html
+++ b/tests/wpt/tests/geolocation-sensor/GeolocationSensor-iframe-access.https.html
@@ -5,10 +5,13 @@
<link rel="help" href="https://wicg.github.io/geolocation-sensor/">
<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="/generic-sensor/resources/generic-sensor-helpers.js"></script>
<script src="/generic-sensor/generic-sensor-iframe-tests.sub.js"></script>
<script src="/generic-sensor/generic-sensor-feature-policy-test.sub.js"></script>
+<script src="resources/sensor-data.js"></script>
<div id="log"></div>
<script>
-run_generic_sensor_iframe_tests('GeolocationSensor');
+run_generic_sensor_iframe_tests(kGeolocationSensorData, kGeolocationReadings);
</script>
diff --git a/tests/wpt/tests/geolocation-sensor/GeolocationSensor.https.html b/tests/wpt/tests/geolocation-sensor/GeolocationSensor.https.html
index b71f964b129..3b4b94e5bbb 100644
--- a/tests/wpt/tests/geolocation-sensor/GeolocationSensor.https.html
+++ b/tests/wpt/tests/geolocation-sensor/GeolocationSensor.https.html
@@ -5,25 +5,12 @@
<link rel="help" href="https://wicg.github.io/geolocation-sensor/">
<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="/page-visibility/resources/window_state_context.js"></script>
<script src="/generic-sensor/resources/generic-sensor-helpers.js"></script>
<script src="/generic-sensor/generic-sensor-tests.js"></script>
+<script src="resources/sensor-data.js"></script>
<script>
-
-'use strict';
-
-const kReadings = {
- readings: [
- [1.12345, 2.12345, 3.12345, 0.95, 0.96, 4.12345, 5.123]
- ],
- expectedReadings: [
- [1.12345, 2.12345, 3.12345, 0.95, 0.96, 4.12345, 5.123]
- ]
-};
-
-runGenericSensorTests(
- 'GeolocationSensor',
- kReadings,
- verifyXyzSensorReading,
- ['geolocation']);
-
+runGenericSensorTests(kGeolocationSensorData, kGeolocationReadings);
</script>
diff --git a/tests/wpt/tests/geolocation-sensor/resources/sensor-data.js b/tests/wpt/tests/geolocation-sensor/resources/sensor-data.js
new file mode 100644
index 00000000000..5bbad442929
--- /dev/null
+++ b/tests/wpt/tests/geolocation-sensor/resources/sensor-data.js
@@ -0,0 +1,17 @@
+'use strict';
+
+const kGeolocationSensorData = {
+ sensorName: 'GeolocationSensor',
+ permissionName: 'geolocation',
+ testDriverName: 'geolocation',
+ featurePolicyNames: ['geolocation']
+};
+
+const kGeolocationReadings = {
+ readings: [
+ [1.12345, 2.12345, 3.12345, 0.95, 0.96, 4.12345, 5.123]
+ ],
+ expectedReadings: [
+ [1.12345, 2.12345, 3.12345, 0.95, 0.96, 4.12345, 5.123]
+ ]
+};
diff --git a/tests/wpt/tests/gyroscope/Gyroscope-iframe-access.https.html b/tests/wpt/tests/gyroscope/Gyroscope-iframe-access.https.html
index ed0183bef9a..c94016764d5 100644
--- a/tests/wpt/tests/gyroscope/Gyroscope-iframe-access.https.html
+++ b/tests/wpt/tests/gyroscope/Gyroscope-iframe-access.https.html
@@ -5,11 +5,14 @@
<link rel="help" href="https://www.w3.org/TR/gyroscope/">
<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="/generic-sensor/resources/generic-sensor-helpers.js"></script>
<script src="/generic-sensor/generic-sensor-iframe-tests.sub.js"></script>
<script src="/generic-sensor/generic-sensor-feature-policy-test.sub.js"></script>
+<script src="resources/sensor-data.js"></script>
<div id="log"></div>
<script>
-run_generic_sensor_iframe_tests('Gyroscope');
+run_generic_sensor_iframe_tests(kGyroscopeSensorData, kGyroscopeReadings);
</script>
diff --git a/tests/wpt/tests/gyroscope/Gyroscope.https.html b/tests/wpt/tests/gyroscope/Gyroscope.https.html
index f85349f5315..8aab94693ab 100644
--- a/tests/wpt/tests/gyroscope/Gyroscope.https.html
+++ b/tests/wpt/tests/gyroscope/Gyroscope.https.html
@@ -6,28 +6,16 @@
<link rel="help" href="https://www.w3.org/TR/gyroscope/">
<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="/page-visibility/resources/window_state_context.js"></script>
<script src="/generic-sensor/resources/generic-sensor-helpers.js"></script>
<script src="/generic-sensor/generic-sensor-tests.js"></script>
+<script src="resources/sensor-data.js"></script>
<script>
'use strict';
-const kReadings = {
- readings: [
- [1.12345, 2.12345, 3.12345]
- ],
- expectedReadings: [
- [1.12345, 2.12345, 3.12345]
- ],
- expectedRemappedReadings: [
- [-2.12345, 1.12345, 3.12345]
- ]
-};
-
-runGenericSensorTests(
- 'Gyroscope',
- kReadings,
- verifyXyzSensorReading,
- ['gyroscope']);
+runGenericSensorTests(kGyroscopeSensorData, kGyroscopeReadings);
</script>
diff --git a/tests/wpt/tests/gyroscope/resources/sensor-data.js b/tests/wpt/tests/gyroscope/resources/sensor-data.js
new file mode 100644
index 00000000000..409ffef9a17
--- /dev/null
+++ b/tests/wpt/tests/gyroscope/resources/sensor-data.js
@@ -0,0 +1,23 @@
+'use strict';
+
+const kGyroscopeSensorData = {
+ sensorName: 'Gyroscope',
+ permissionName: 'gyroscope',
+ testDriverName: 'gyroscope',
+ featurePolicyNames: ['gyroscope']
+};
+
+// Due to the gyroscope input values being rounded using a precision of
+// 0.1 deg/sec, the expectedReadings and expectedRemappedReadings contain
+// a significant number of decimal places.
+const kGyroscopeReadings = {
+ readings: [
+ { x: 1, y: 2, z: 3 }
+ ],
+ expectedReadings: [
+ { x: 1.00007366, y: 2.00014732, z: 3.00022098 }
+ ],
+ expectedRemappedReadings: [
+ { x: -2.00014732, y: 1.00007366, z: 3.00022098 }
+ ]
+};
diff --git a/tests/wpt/tests/hr-time/raf-coarsened-time.https.html b/tests/wpt/tests/hr-time/raf-coarsened-time.https.html
new file mode 100644
index 00000000000..c7cc723da6f
--- /dev/null
+++ b/tests/wpt/tests/hr-time/raf-coarsened-time.https.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<html>
+<head>
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/webappapis.html#update-the-rendering">
+ <script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script>
+ /* Coarsen to 5 microseconds or coarser */
+ const COARSE_RESOLUTION = 0.005;
+
+ const CUSTOM_TIMELINE_DELTA = 0.002;
+ const FLOATING_POINT_ERROR_EPSILON = 0.00001;
+
+ // Note that this test would fail if the platform introduces a jitter.
+ // It is recommended that platforms that implement jitter run this test
+ // with a flag that turns jitter off, if possible.
+
+ const customTimeline = new DocumentTimeline({originTime: CUSTOM_TIMELINE_DELTA});
+ promise_test(async t => {
+ for (let i = 0; i < 32; ++i) {
+ const timestamp = await new Promise(resolve => requestAnimationFrame(ts => resolve(ts)));
+ const coarse_timestamp = Math.round(timestamp / COARSE_RESOLUTION) * COARSE_RESOLUTION;
+ assert_approx_equals(timestamp, coarse_timestamp, FLOATING_POINT_ERROR_EPSILON);
+ assert_approx_equals(timestamp, document.timeline.currentTime, FLOATING_POINT_ERROR_EPSILON);
+ assert_approx_equals(customTimeline.currentTime + CUSTOM_TIMELINE_DELTA,
+ timestamp, FLOATING_POINT_ERROR_EPSILON);
+ }
+ });
+</script>
+</body>
+</html>
diff --git a/tests/wpt/tests/hr-time/raf-coarsened-time.https.html.headers b/tests/wpt/tests/hr-time/raf-coarsened-time.https.html.headers
new file mode 100644
index 00000000000..5f8621ef836
--- /dev/null
+++ b/tests/wpt/tests/hr-time/raf-coarsened-time.https.html.headers
@@ -0,0 +1,2 @@
+Cross-Origin-Embedder-Policy: require-corp
+Cross-Origin-Opener-Policy: same-origin
diff --git a/tests/wpt/tests/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/order-in-bfcache-restore.html b/tests/wpt/tests/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/order-in-bfcache-restore.html
new file mode 100644
index 00000000000..f453c80a2ae
--- /dev/null
+++ b/tests/wpt/tests/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/order-in-bfcache-restore.html
@@ -0,0 +1,70 @@
+<!DOCTYPE html>
+<title>pagereveal event fires and in correct order on restoration from BFCache</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/browsing-the-web.html#updating-the-document">
+<link rel="author" href="mailto:bokan@chromium.org">
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/utils.js"></script>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="/html/browsers/browsing-the-web/back-forward-cache/resources/helper.sub.js"></script>
+<script>
+// runBfcacheTest opens a popup to pageA which navigates to pageB and then
+// back, ensuring pageA is stored in the BFCache.
+runBfcacheTest({
+ funcBeforeNavigation: async () => {
+ // This function executes in pageA
+
+ // Wait for an animation frame to ensure the the initial-load
+ // `pagereveal` has already been fired so it doesn't get recorded
+ // below.
+ const raf = new Promise(resolve => requestAnimationFrame(resolve));
+ await raf;
+
+ window.event_log = [];
+ let restored = false;
+
+ function recordRafs() {
+ requestAnimationFrame( () => {
+ // Avoid recording animation frames until the page is restored from
+ // BFCache since it's currently uncached. This test is interested only
+ // in the behavior during restoration.
+ if (restored)
+ window.event_log.push('rAF');
+
+ recordRafs();
+ });
+ }
+
+ recordRafs();
+
+ addEventListener('pageshow', (e) => {
+ window.event_log.push('pageshow' + (e.persisted ? '.persisted' : ''));
+ if (e.persisted)
+ restored = true;
+ });
+
+ addEventListener('pagereveal', () => {
+ window.event_log.push('pagereveal');
+ });
+ },
+ funcAfterAssertion: async (pageA, pageB, t) => {
+ let event_log = await pageA.execute_script(async () => {
+ // Ensure at least one animation frame is produced to ensure
+ // pagereveal must have fired.
+ await new Promise(requestAnimationFrame);
+ return window.event_log;
+ });
+
+ // Expect that the events seen are:
+ // pageshow.persisted, pagereveal, rAF, rAF, rAF, ...
+ assert_equals(event_log.slice(0, 3).toString(),
+ 'pageshow.persisted,pagereveal,rAF');
+ for (let i = 3; i < event_log.length; ++i) {
+ assert_equals(event_log[i], 'rAF',
+ 'All events following pagereveal should be animation frames');
+ }
+ },
+ targetOrigin: originSameOrigin,
+});
+</script>
diff --git a/tests/wpt/tests/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/order-in-new-document-navigation.html b/tests/wpt/tests/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/order-in-new-document-navigation.html
new file mode 100644
index 00000000000..d2c44511d3a
--- /dev/null
+++ b/tests/wpt/tests/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/order-in-new-document-navigation.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<title>pagereveal event fires and in correct order on new-document navigation</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/webappapis.html#update-the-rendering">
+<link rel="author" href="mailto:bokan@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+const event_log = [];
+
+addEventListener('pageshow', () => event_log.push('pageshow'));
+addEventListener('pagereveal', () => event_log.push('pagereveal'));
+requestAnimationFrame(() => event_log.push('rAF'));
+
+promise_test(async () => {
+ await new Promise(resolve => requestAnimationFrame(resolve));
+ assert_equals(event_log.toString(),'pageshow,pagereveal,rAF');
+});
+</script>
diff --git a/tests/wpt/tests/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/order-in-prerender-activation.html b/tests/wpt/tests/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/order-in-prerender-activation.html
new file mode 100644
index 00000000000..b281b2b0881
--- /dev/null
+++ b/tests/wpt/tests/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/order-in-prerender-activation.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<title>pagereveal event fires and in correct order on prerender activation</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/webappapis.html#update-the-rendering">
+<link rel="author" href="mailto:bokan@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/utils.js"></script>
+<script src="/speculation-rules/resources/utils.js"></script>
+<script src="/speculation-rules/prerender/resources/utils.js"></script>
+<script>
+setup(() => assertSpeculationRulesIsSupported());
+
+const uid = token();
+const initiator_url = `resources/order-in-prerender-activation-popup.html?uid=${uid}`;
+
+// This test opens a popup to an initiator page. That page then prerenders a
+// "prerendering" version of itself (by adding a `prerendering` query param)
+// and navigates itself to activate the prerender. The results are recorded and
+// sent back to this test harness.
+promise_test(async () => {
+ const channel = new PrerenderChannel('result', uid);
+ const test_done = new Promise(resolve => {
+ channel.addEventListener('message', e => resolve(e.data), { once: true });
+ });
+
+ window.open(initiator_url, '_blank', 'noopener');
+
+ const result = await test_done;
+
+ if (result.hasOwnProperty('fail')) {
+ assert_unreached(result.fail);
+ }
+
+ // The test records relevant event occurrences up to the second animation
+ // frame. Ensure their order and apparance is as expected.
+ const events_in_order = result.events.join(',');
+ assert_equals(events_in_order,
+ 'pageshow,prerenderingchange,pagereveal,raf');
+});
+</script>
diff --git a/tests/wpt/tests/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/resources/order-in-prerender-activation-popup.html b/tests/wpt/tests/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/resources/order-in-prerender-activation-popup.html
new file mode 100644
index 00000000000..78989adc172
--- /dev/null
+++ b/tests/wpt/tests/html/browsers/browsing-the-web/history-traversal/pagereveal/tentative/resources/order-in-prerender-activation-popup.html
@@ -0,0 +1,74 @@
+<!DOCTYPE html>
+<title>pagereveal event fires and in correct order on prerender activation (popup)</title>
+<link rel="author" href="mailto:bokan@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/speculation-rules/prerender/resources/utils.js"></script>
+<script>
+const params = new URLSearchParams(location.search);
+const uid = params.get('uid');
+const is_prerender_step = params.has('prerendering');
+
+const ready_channel = new PrerenderChannel('ready-to-activate', uid);
+
+function finish(result) {
+ const result_channel = new PrerenderChannel('result', uid);
+ result_channel.postMessage(result);
+ result_channel.close();
+ window.close();
+}
+
+// testharness.js assertions don't work inside this popup so this small helper
+// sends a failure signal back to the test page which will cause test failure.
+function assert(cond, desc) {
+ if (!cond) {
+ finish({fail: desc});
+ }
+}
+
+// The first load of this page should be without 'prerendering' and is used
+// to setup the prerender and then activate it when it's ready.
+if (!is_prerender_step) {
+ assert(!document.prerendering, 'initiator page must not be prerendered');
+
+ const ready_to_activate = new Promise(resolve => {
+ ready_channel.addEventListener('message', resolve, {once: true});
+ });
+
+ const prerendering_url = location.href + '&prerendering';
+ startPrerendering(prerendering_url);
+
+ ready_to_activate.then(() => {
+ location.replace(prerendering_url);
+ });
+} else {
+ assert(document.prerendering, 'prerendering step must be initially prerendered');
+
+ const result = {
+ events: []
+ };
+
+ document.addEventListener('prerenderingchange', () => {
+ result.events.push('prerenderingchange');
+ });
+
+ addEventListener('pageshow', () => {
+ result.events.push('pageshow');
+ });
+
+ // A second rAF will end the test.
+ requestAnimationFrame(() => {
+ result.events.push('raf');
+ requestAnimationFrame(() => finish(result));
+ });
+
+ addEventListener('pagereveal', () => {
+ result.events.push('pagereveal');
+ });
+
+ addEventListener('load', () => {
+ ready_channel.postMessage('unused-readyToActivateMessage');
+ ready_channel.close();
+ });
+}
+</script>
diff --git a/tests/wpt/tests/html/dom/elements/global-attributes/dir-auto-form-associated.window.js b/tests/wpt/tests/html/dom/elements/global-attributes/dir-auto-form-associated.window.js
new file mode 100644
index 00000000000..1777f75259b
--- /dev/null
+++ b/tests/wpt/tests/html/dom/elements/global-attributes/dir-auto-form-associated.window.js
@@ -0,0 +1,61 @@
+// Keep this mostly synchronized with
+// html/semantics/forms/attributes-common-to-form-controls/dirname-only-if-applies.html
+// except that won't have "reset" and "button" as those don't submit their value
+[
+ "hidden",
+ "text",
+ "search",
+ "tel",
+ "url",
+ "email",
+ "password",
+ "submit",
+ "reset",
+ "button"
+].forEach(type => {
+ test(t => {
+ const input = document.createElement("input");
+ t.add_cleanup(() => input.remove());
+ input.type = type;
+ assert_equals(input.type, type);
+ input.dir = "auto";
+ input.value = "\u05D0"; // The Hebrew letter Alef (strongly RTL)
+ document.body.append(input);
+ assert_true(input.matches(":dir(rtl)"));
+ }, `<input dir=auto type=${type}> directionality`);
+});
+
+[
+ "date",
+ "month",
+ "week",
+ "time",
+ "datetime-local",
+ "number",
+ "range",
+ "color",
+ "checkbox",
+ "radio",
+ // "file" // value setter throws
+ "image"
+].forEach(type => {
+ test(t => {
+ const input = document.createElement("input");
+ t.add_cleanup(() => input.remove());
+ input.type = type;
+ assert_equals(input.type, type);
+ input.dir = "auto";
+ input.value = "\u05D0"; // The Hebrew letter Alef (strongly RTL)
+ document.body.append(input);
+ assert_true(input.matches(":dir(ltr)"));
+ }, `<input dir=auto type=${type}> directionality`);
+});
+
+test(t => {
+ const input = document.createElement("textarea");
+ t.add_cleanup(() => input.remove());
+ input.dir = "auto";
+ input.value = "\u05D0"; // The Hebrew letter Alef (strongly RTL)
+ document.body.append(input);
+ assert_true(input.matches(":dir(rtl)"));
+}, `<textarea dir=auto> directionality`);
diff --git a/tests/wpt/tests/html/dom/elements/global-attributes/lang-attribute.window.js b/tests/wpt/tests/html/dom/elements/global-attributes/lang-attribute.window.js
new file mode 100644
index 00000000000..de0c03e6f85
--- /dev/null
+++ b/tests/wpt/tests/html/dom/elements/global-attributes/lang-attribute.window.js
@@ -0,0 +1,16 @@
+test(() => {
+ const container = document.createElement("div");
+ document.body.append(container);
+ container.setAttribute("lang", "en-CA");
+
+ const child = document.createElementNS("div", "test");
+ container.append(child);
+ child.setAttribute("lang", "en-NZ");
+
+ assert_true(container.matches(":lang(en-CA)"), "container matches en-CA");
+ assert_true(child.matches(":lang(en-CA)"), "child matches en-CA");
+ assert_false(container.matches(":lang(en-NZ)"), "container does not match en-NZ");
+ assert_false(child.matches(":lang(en-NZ)"), "child does not match en-NZ");
+
+ container.remove();
+}, "unnamespaced lang attribute only works on elements in the HTML namespace");
diff --git a/tests/wpt/tests/html/dom/elements/global-attributes/lang-xmllang-01-ref.html b/tests/wpt/tests/html/dom/elements/global-attributes/lang-xmllang-01-ref.html
index 1606bca2158..eacf73da16c 100644
--- a/tests/wpt/tests/html/dom/elements/global-attributes/lang-xmllang-01-ref.html
+++ b/tests/wpt/tests/html/dom/elements/global-attributes/lang-xmllang-01-ref.html
@@ -2,7 +2,7 @@
<title>Languages</title>
<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-lang-and-xml:lang-attributes">
-<link tel="help" href="http://www.w3.org/TR/CSS2/selector.html#lang">
+<link rel="help" href="http://www.w3.org/TR/CSS2/selector.html#lang">
<meta name="flags" content="css21">
<style>
#test > * { background: limegreen; }
diff --git a/tests/wpt/tests/html/dom/elements/global-attributes/lang-xmllang-01.html b/tests/wpt/tests/html/dom/elements/global-attributes/lang-xmllang-01.html
index 9538f15ca8c..04d8b74e2d1 100644
--- a/tests/wpt/tests/html/dom/elements/global-attributes/lang-xmllang-01.html
+++ b/tests/wpt/tests/html/dom/elements/global-attributes/lang-xmllang-01.html
@@ -3,7 +3,7 @@
<link rel="match" href="lang-xmllang-01-ref.html">
<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-lang-and-xml:lang-attributes">
-<link tel="help" href="http://www.w3.org/TR/CSS2/selector.html#lang">
+<link rel="help" href="http://www.w3.org/TR/CSS2/selector.html#lang">
<meta name="flags" content="css21">
<style>
#test #a :lang(en) { background: limegreen; }
diff --git a/tests/wpt/tests/html/dom/elements/global-attributes/lang-xyzzy.html b/tests/wpt/tests/html/dom/elements/global-attributes/lang-xyzzy.html
index d6e6aeb6475..b950e1fac99 100644
--- a/tests/wpt/tests/html/dom/elements/global-attributes/lang-xyzzy.html
+++ b/tests/wpt/tests/html/dom/elements/global-attributes/lang-xyzzy.html
@@ -3,7 +3,7 @@
<link rel="match" href="lang-xyzzy-ref.html">
<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-lang-and-xml:lang-attributes">
-<link tel="help" href="http://www.w3.org/TR/CSS2/selector.html#lang">
+<link rel="help" href="http://www.w3.org/TR/CSS2/selector.html#lang">
<meta name="flags" content="css21">
<style>:lang(xyzzy) { color: green; }</style>
<body>
diff --git a/tests/wpt/tests/html/infrastructure/urls/base-url/document-base-uri-synthetic-document.html b/tests/wpt/tests/html/infrastructure/urls/base-url/document-base-uri-synthetic-document.html
new file mode 100644
index 00000000000..bed090aac42
--- /dev/null
+++ b/tests/wpt/tests/html/infrastructure/urls/base-url/document-base-uri-synthetic-document.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<link rel=author href="mailto:jarhar@chromium.org">
+<link rel=help href="https://bugs.chromium.org/p/chromium/issues/detail?id=1486750">
+<link rel=help href="https://html.spec.whatwg.org/multipage/urls-and-fetching.html#document-base-url">
+<link rel=help href="https://html.spec.whatwg.org/multipage/urls-and-fetching.html#fallback-base-url">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<body>
+<script>
+test(() => {
+ const doc1 = document.implementation.createHTMLDocument();
+ assert_equals(doc1.baseURI, 'about:blank', 'document.implementation.createHTMLDocument()');
+
+ const doc2 = document.implementation.createDocument('', '');
+ assert_equals(doc2.baseURI, 'about:blank', 'document.implementation.createDocument("", "")');
+
+ const doc3 = new Document();
+ assert_equals(doc3.baseURI, 'about:blank', 'new Document()');
+}, 'Synthetic documents should return about:blank for document.baseURI.');
+
+test(() => {
+ const doc = document.implementation.createHTMLDocument();
+ assert_equals(doc.baseURI, 'about:blank', 'baseURI should be about:blank without a <base>.');
+
+ const base = doc.createElement('base');
+ base.href = '/foo';
+ doc.head.appendChild(base);
+ assert_equals(doc.baseURI, 'about:blank', '<base> with relative URL should not change the about:blank baseURI.');
+
+ base.href = 'http://example.com/';
+ assert_equals(doc.baseURI, 'http://example.com/', '<base> with complete URL should replace the about:blank baseURI.');
+}, 'Synthetic documents should incorporate <base> href URLs correctly.');
+</script>
diff --git a/tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-viewport-001.html b/tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-viewport-001.html
new file mode 100644
index 00000000000..408e5309e57
--- /dev/null
+++ b/tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-viewport-001.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+ <meta charset="utf-8">
+ <link rel="match" href="iframe-loading-lazy-in-viewport-ref.html">
+ <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1860041">
+</head>
+<body>
+ <iframe loading="lazy" src="data:text/html,PASS" onload="document.documentElement.className = ''"></iframe>
+ <script>
+ document.querySelector("iframe").getBoundingClientRect();
+ </script>
+</body>
+</html>
diff --git a/tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-viewport-ref.html b/tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-viewport-ref.html
new file mode 100644
index 00000000000..067bfa19202
--- /dev/null
+++ b/tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-viewport-ref.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<iframe src="data:text/html,PASS"></iframe>
diff --git a/tests/wpt/tests/html/semantics/embedded-content/the-img-element/img-src-in-synthetic-document.html b/tests/wpt/tests/html/semantics/embedded-content/the-img-element/img-src-in-synthetic-document.html
new file mode 100644
index 00000000000..24c5567fb85
--- /dev/null
+++ b/tests/wpt/tests/html/semantics/embedded-content/the-img-element/img-src-in-synthetic-document.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<link rel=author href="mailto:jarhar@chromium.org">
+<link rel=help href="https://github.com/whatwg/html/issues/9855">
+<link rel=help href="https://html.spec.whatwg.org/#reflecting-content-attributes-in-idl-attributes">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<script>
+test(() => {
+ const doc = document.implementation.createHTMLDocument('');
+ const img = doc.createElement('img');
+ img.setAttribute('src', '/test');
+ doc.body.appendChild(img);
+ assert_equals(img.src, '/test');
+}, 'HTMLImageElement.src should return the string from the attribute in about:blank documents.');
+</script>
diff --git a/tests/wpt/tests/html/semantics/forms/attributes-common-to-form-controls/dirname-only-if-applies.html b/tests/wpt/tests/html/semantics/forms/attributes-common-to-form-controls/dirname-only-if-applies.html
index 1fd0476e314..8af6826fa13 100644
--- a/tests/wpt/tests/html/semantics/forms/attributes-common-to-form-controls/dirname-only-if-applies.html
+++ b/tests/wpt/tests/html/semantics/forms/attributes-common-to-form-controls/dirname-only-if-applies.html
@@ -13,19 +13,24 @@
<div id="log"></div>
<form action="resources/dirname-iframe.html" method=get target="iframe">
<textarea name="textarea" dirname="textarea.dir"></textarea>
- <p><button id="btn-submit" type=submit>Submit</button></p>
+ <p><input id="btn-submit" type=submit name=submit dirname=submit.dir value=Submit></p>
</form>
<iframe name="iframe"></iframe>
<script>
- const types_applies = ["text", "search", "hidden", "tel", "url", "email"];
+ const types_applies = [
+ "hidden", "text", "search", "tel", "url", "email", "password", "submit"
+ ];
const types_not = [
- "password", "date", "month", "week", "time", "image", "reset", "button",
- "datetime-local", "number", "range", "color", "checkbox", "radio", "file", "submit",
+ "date", "month", "week", "time", "datetime-local", "number", "range", "color", "checkbox",
+ "radio", "file", "image", "reset", "button"
];
const types = [...types_applies, ...types_not];
let form = document.querySelector("form");
for (const type of types) {
+ if (type === "submit") {
+ continue;
+ }
let p = document.createElement("p");
let lbl = document.createElement("label");
let txt = document.createTextNode(type + ": ");
@@ -52,7 +57,8 @@
}
}
- const data = new FormData(form);
+ const submitter = document.getElementById("btn-submit");
+ const data = new FormData(form, submitter);
test(function() {
assertInputSubmission(data);
}, "Submit input element directionality to FormData, if dirname applies.");
@@ -60,7 +66,7 @@
assert_equals(data.get("textarea.dir"), "ltr", "Submit ltr for textarea");
}, "Submit textarea element directionality to FormData.");
- document.getElementById("btn-submit").click();
+ submitter.click();
const t_inp = async_test("Submit input element directionality, if dirname applies.");
onIframeLoadedDone(t_inp, function(params) {
assertInputSubmission(params);
diff --git a/tests/wpt/tests/html/semantics/forms/the-input-element/input-disabled-fieldset-dynamic.html b/tests/wpt/tests/html/semantics/forms/the-input-element/input-disabled-fieldset-dynamic.html
new file mode 100644
index 00000000000..eefcd972bf1
--- /dev/null
+++ b/tests/wpt/tests/html/semantics/forms/the-input-element/input-disabled-fieldset-dynamic.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<meta charset="utf-8">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1861027">
+<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>
+<fieldset id="fieldset" disabled>
+ <input id="target">
+</fieldset>
+<script>
+const target = document.getElementById("target");
+const fieldset = document.getElementById("fieldset");
+promise_test(async function() {
+ await new Promise(r => window.addEventListener("load", r, { once: true }));
+ assert_true(target.matches(":disabled"), "Fieldset disables the input");
+ assert_true(target.matches(":read-only"), "Disabled implies read-only");
+
+ // Try to focus, it shouldn't be focusable.
+ target.focus();
+
+ assert_not_equals(document.activeElement, target, "Should not be focusable");
+
+ fieldset.removeAttribute("disabled");
+
+ assert_false(target.matches(":disabled"), "Should go back to writable");
+ assert_false(target.matches(":read-only"), "No longer read-only");
+
+ // Should be focusable now.
+ target.focus();
+
+ assert_equals(document.activeElement, target, "Should not be focusable");
+
+ await test_driver.send_keys(target, "A");
+ assert_equals(target.value, "A", "Typing should work");
+});
+</script>
diff --git a/tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/dialog-cancel-events.html b/tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/dialog-cancel-events.html
index 7133ce3ca04..d583c4cd23c 100644
--- a/tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/dialog-cancel-events.html
+++ b/tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/dialog-cancel-events.html
@@ -1,70 +1,53 @@
<!DOCTYPE html>
-<html>
-<head>
- <title>Test cancel event is fired when the dialog is closed by user interaction</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>
- <link rel="help" href="https://bugs.webkit.org/show_bug.cgi?id=227534">
- <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1322947">
-</head>
-<body>
-<p>Test cancel event is fired when the dialog is closed by user interaction</p>
+<meta charset="utf-8">
+<title>Test cancel event is fired when the dialog is closed by user close requests</title>
+<link rel="help" href="https://bugs.webkit.org/show_bug.cgi?id=227534">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1322947">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script src="/common/top-layer.js"></script>
+<script src="/close-watcher/resources/helpers.js"></script>
+
<dialog>
<p>Hello World</p>
</dialog>
-<script>
- setup({ single_test: true });
- var hasCancelEventFired = false;
- var hasCloseEventFired = false;
- var oncancelWasCalled = false;
- var oncloseWasCalled = false;
+<script type="module">
+setup({ single_test: true });
+
+const dialog = document.querySelector("dialog");
+const events = [];
+
+dialog.addEventListener("cancel", event => {
+ assert_true(event.cancelable, "cancel event should be cancelable");
+ assert_array_equals(events, []);
+
+ events.push("addEventListener cancel");
+});
- function maybeDone() {
- if (oncloseWasCalled && hasCloseEventFired) {
- done();
- }
- }
+assert_equals(dialog.oncancel, null);
+dialog.oncancel = () => {
+ assert_array_equals(events, ["addEventListener cancel"]);
- const dialog = document.querySelector("dialog");
+ events.push("oncancel");
+};
- dialog.addEventListener("cancel", function(event) {
- assert_true(true, "cancel event is fired");
- assert_true(event.cancelable, "cancel event should be cancelable");
- assert_false(hasCancelEventFired, "cancel event should only be fired once");
- assert_false(hasCloseEventFired, "close event should be fired after cancel event");
- hasCancelEventFired = true;
- });
+dialog.addEventListener("close", () => {
+ assert_array_equals(events, ["addEventListener cancel", "oncancel"]);
- assert_equals(dialog.oncancel, null);
- dialog.oncancel = function(event) {
- assert_true(true, "oncancel event handler is called");
- assert_false(oncancelWasCalled, "oncancel handler should only be called once");
- assert_false(oncloseWasCalled, "onclose handler should be called after oncancel");
- oncancelWasCalled = true;
- }
+ events.push("addEventListener close");
+});
- dialog.addEventListener("close", function() {
- assert_true(true, "close event is fired");
- assert_false(hasCloseEventFired, "close event should only be fired once");
- assert_true(hasCancelEventFired, "cancel event should be fired before close event");
- hasCloseEventFired = true;
- maybeDone();
- });
+assert_equals(dialog.onclose, null);
+dialog.onclose = () => {
+ assert_array_equals(events, ["addEventListener cancel", "oncancel", "addEventListener close"]);
- assert_equals(dialog.onclose, null);
- dialog.onclose = function(event) {
- assert_true(true, "onclose event handler is called");
- assert_false(oncloseWasCalled, "onclose handler should only be called once");
- assert_true(oncancelWasCalled, "oncancel handler should be called before onclose");
- oncloseWasCalled = true;
- maybeDone();
- }
+ done();
+};
- dialog.showModal();
- test_driver.send_keys(document.documentElement, "\uE00C"); // ESC key
+dialog.showModal();
+await blessTopLayer(dialog);
+await sendCloseRequest();
</script>
-</body>
-</html>
diff --git a/tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/dialog-cancel-preventDefault.html b/tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/dialog-cancel-preventDefault.html
index 79728b649f4..4daffc09a46 100644
--- a/tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/dialog-cancel-preventDefault.html
+++ b/tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/dialog-cancel-preventDefault.html
@@ -6,6 +6,8 @@
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
+ <script src="/common/top-layer.js"></script>
+ <script src="/close-watcher/resources/helpers.js"></script>
<link rel="help" href="https://bugs.webkit.org/show_bug.cgi?id=227534">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1322947">
</head>
@@ -14,7 +16,7 @@
<dialog>
<p>Hello World</p>
</dialog>
-<script>
+<script type=module>
setup({ single_test: true });
var hasCancelEventFired = false;
@@ -39,7 +41,9 @@
});
dialog.showModal();
- test_driver.send_keys(document.documentElement, "\uE00C"); // ESC key
+
+ await blessTopLayer(dialog);
+ await sendCloseRequest();
</script>
</body>
</html>
diff --git a/tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/dialog-canceling.html b/tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/dialog-canceling.html
index fc003d29d19..e368bde6fb3 100644
--- a/tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/dialog-canceling.html
+++ b/tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/dialog-canceling.html
@@ -8,6 +8,8 @@
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-actions.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
+<script src="/common/top-layer.js"></script>
+<script src="/close-watcher/resources/helpers.js"></script>
<!--
To test manually, hit Escape once to see the topmost dialog turn green
@@ -44,13 +46,6 @@ then once again to close it. Repeat for the remaining dialog.
</dialog>
<script>
-async function pressEscape() {
- const actions = new test_driver.Actions()
- .keyDown('\uE00C')
- .keyUp('\uE00C');
- await actions.send();
-}
-
function handleCancel(event) {
this.style.background = 'green';
this.querySelector('span').textContent = 'I blocked the cancel! Try again to close me.';
@@ -72,33 +67,36 @@ promise_test(async () => {
});
bottomDialog.showModal();
+ await blessTopLayer(bottomDialog);
topDialog.showModal();
- await pressEscape();
+ await blessTopLayer(topDialog);
+ await sendEscKey();
assert_true(topDialog.open, 'Top dialog event listener should prevent closing.');
assert_true(bottomDialog.open, 'Top dialog event listener should prevent closing.');
- await pressEscape();
+ await blessTopLayer(topDialog);
+ await sendEscKey();
assert_false(topDialog.open, 'Top dialog should close.');
assert_true(bottomDialog.open, 'Top dialog should close.');
swallowInput.focus();
- await pressEscape();
- await pressEscape();
- await pressEscape();
+ await sendEscKey();
+ await sendEscKey();
+ await sendEscKey();
assert_false(topDialog.open, 'Input should swallow Escape mechanism.');
assert_true(bottomDialog.open, 'Input should swallow Escape mechanism.');
normalInput.focus();
- await pressEscape();
+ await sendEscKey();
assert_false(topDialog.open, 'Bottom dialog event listener should prevent closing.');
assert_true(bottomDialog.open, 'Bottom dialog event listener should prevent closing.');
- await pressEscape();
+ await sendEscKey();
assert_false(topDialog.open, 'Bottom dialog should close.');
assert_false(bottomDialog.open, 'Bottom dialog should close.');
- await pressEscape();
+ await sendEscKey();
assert_false(topDialog.open, 'Pressing Escape now should do nothing.');
assert_false(bottomDialog.open, 'Pressing Escape now should do nothing.');
diff --git a/tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/focus-previous-iframe.tentative.html b/tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/focus-previous-iframe.tentative.html
new file mode 100644
index 00000000000..c31daa48766
--- /dev/null
+++ b/tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/focus-previous-iframe.tentative.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width,initial-scale=1">
+<title>Test focus is moved to the previously focused element when dialog is closed</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-actions.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+
+<body>
+<dialog>Dialog in parent</dialog>
+
+<iframe srcdoc="<input><dialog> Dialog in child </dialog>"></iframe>
+
+<input>
+<script>
+test(() => {
+ window.onload = function() {
+ const iframe = document.querySelector("iframe");
+ const input = iframe.contentDocument.querySelector("input");
+ // <input> in the child document is focused
+ input.focus();
+
+ const dialog = document.querySelector("dialog");
+ // <dialog> in the parent document is opened
+ dialog.showModal();
+ dialog.close();
+
+ assert_equals(document.activeElement, iframe);
+ assert_equals(iframe.contentDocument.activeElement, input);
+ }
+}, "Focus should move back from parent document to child document");
+
+test(() => {
+ window.onload = function() {
+ const iframe = document.querySelector("iframe");
+ const input = document.querySelector("input");
+ // <input> in the parent document is focused
+ input.focus();
+
+ const dialog = iframe.contentDocument.querySelector("dialog");
+
+ // <dialog> in the child document is focused
+ dialog.showModal();
+ dialog.close();
+
+ assert_equals(document.activeElement, input);
+ }
+}, "Focus should move back from child document to parent document");
+</script>
+</body>
diff --git a/tests/wpt/tests/html/semantics/invokers/invokeelement-interface.tentative.html b/tests/wpt/tests/html/semantics/invokers/invokeelement-interface.tentative.html
index 69cfd80fe56..b003daf20d4 100644
--- a/tests/wpt/tests/html/semantics/invokers/invokeelement-interface.tentative.html
+++ b/tests/wpt/tests/html/semantics/invokers/invokeelement-interface.tentative.html
@@ -17,8 +17,8 @@
const div = document.body.appendChild(document.createElement("div"));
invoker.invokeTargetElement = div;
assert_equals(invoker.invokeTargetElement, div);
- assert_equals(invoker.getAttribute('invoketarget'), '');
- assert_false(invoker.hasAttribute('invokeaction'));
+ assert_equals(invoker.getAttribute("invoketarget"), "");
+ assert_false(invoker.hasAttribute("invokeaction"));
}, "invokeTargetElement reflects set value");
test(function () {
@@ -27,8 +27,8 @@
const button = shadow.appendChild(document.createElement("button"));
button.invokeTargetElement = invokee;
assert_equals(button.invokeTargetElement, invokee);
- assert_equals(invoker.getAttribute('invoketarget'), '');
- assert_false(invoker.hasAttribute('invokeaction'));
+ assert_equals(invoker.getAttribute("invoketarget"), "");
+ assert_false(invoker.hasAttribute("invokeaction"));
}, "invokeTargetElement reflects set value across shadow root into light dom");
test(function () {
@@ -37,8 +37,8 @@
const div = shadow.appendChild(document.createElement("div"));
invoker.invokeTargetElement = div;
assert_equals(invoker.invokeTargetElement, null);
- assert_equals(invoker.getAttribute('invoketarget'), '');
- assert_false(invoker.hasAttribute('invokeaction'));
+ assert_equals(invoker.getAttribute("invoketarget"), "");
+ assert_false(invoker.hasAttribute("invokeaction"));
}, "invokeTargetElement does not reflect set value inside shadowroot");
test(function () {
@@ -52,7 +52,7 @@
}, "invokeTargetElement throws error on assignment of non Element");
test(function () {
- assert_false(invoker.hasAttribute('invokeaction'));
+ assert_false(invoker.hasAttribute("invokeaction"));
assert_equals(invoker.invokeAction, "auto");
}, "invokeAction reflects 'auto' when attribute not present");
@@ -64,6 +64,7 @@
test(function () {
invoker.invokeAction = "fooBarBaz";
+ assert_equals(invoker.getAttribute("invokeaction"), "fooBarBaz");
assert_equals(invoker.invokeAction, "fooBarBaz");
}, "invokeAction reflects same casing");
diff --git a/tests/wpt/tests/html/semantics/invokers/invokeevent-interface.tentative.html b/tests/wpt/tests/html/semantics/invokers/invokeevent-interface.tentative.html
index 007c97e6fe5..82910b3d441 100644
--- a/tests/wpt/tests/html/semantics/invokers/invokeevent-interface.tentative.html
+++ b/tests/wpt/tests/html/semantics/invokers/invokeevent-interface.tentative.html
@@ -46,6 +46,11 @@
}, "action set to false");
test(function () {
+ const event = new InvokeEvent("test", { action: "" });
+ assert_equals(event.action, "");
+ }, "action explicitly set to empty string");
+
+ test(function () {
const event = new InvokeEvent("test", { action: true });
assert_equals(event.action, "true");
}, "action set to true");
@@ -57,7 +62,7 @@
test(function () {
const event = new InvokeEvent("test", { action: [] });
- assert_equals(event.action, "auto");
+ assert_equals(event.action, "");
}, "action set to []");
test(function () {
@@ -73,13 +78,13 @@
test(function () {
const event = new InvokeEvent("test", {
action: {
- valueOf: function () {
+ toString() {
return "sample";
},
},
});
- assert_equals(event.action, "[object Object]");
- }, "action set to an object with a valueOf function");
+ assert_equals(event.action, "sample");
+ }, "action set to an object with a toString function");
test(function () {
const eventInit = { action: "sample", invoker: document.body };
diff --git a/tests/wpt/tests/html/semantics/invokers/invoketarget-on-popover-behavior.tentative.html b/tests/wpt/tests/html/semantics/invokers/invoketarget-on-popover-behavior.tentative.html
new file mode 100644
index 00000000000..9d9bbaee721
--- /dev/null
+++ b/tests/wpt/tests/html/semantics/invokers/invoketarget-on-popover-behavior.tentative.html
@@ -0,0 +1,193 @@
+<!doctype html>
+<meta charset="utf-8" />
+<meta name="author" title="Keith Cirkel" href="mailto:keithamus@github.com" />
+<link rel="help" href="https://open-ui.org/components/invokers.explainer/" />
+<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/invoker-utils.js"></script>
+
+<div id="invokee" popover>
+ <button id="invokerbutton2" invoketarget="invokee"></button>
+</div>
+<button id="invokerbutton" invoketarget="invokee"></button>
+
+<script>
+ // auto
+
+ promise_test(async function (t) {
+ assert_false(invokee.matches(":popover-open"));
+ await clickOn(invokerbutton);
+ t.add_cleanup(() => invokee.hidePopover());
+ assert_true(invokee.matches(":popover-open"));
+ }, "invoking (as auto) closed popover opens");
+
+ promise_test(async function (t) {
+ assert_false(invokee.matches(":popover-open"));
+ invokee.addEventListener("invoke", (e) => e.preventDefault(), {
+ once: true,
+ });
+ await clickOn(invokerbutton);
+ t.add_cleanup(() => invokee.hidePopover());
+ assert_false(invokee.matches(":popover-open"));
+ }, "invoking (as auto) closed popover with preventDefault does not open");
+
+ promise_test(async function (t) {
+ invokee.showPopover();
+ assert_true(invokee.matches(":popover-open"));
+ await clickOn(invokerbutton2);
+ assert_false(invokee.matches(":popover-open"));
+ }, "invoking (as auto) open popover closes");
+
+ promise_test(async function (t) {
+ invokee.showPopover();
+ t.add_cleanup(() => invokee.hidePopover());
+ invokee.addEventListener("invoke", (e) => e.preventDefault(), {
+ once: true,
+ });
+ assert_true(invokee.matches(":popover-open"));
+ await clickOn(invokerbutton2);
+ assert_true(invokee.matches(":popover-open"));
+ }, "invoking (as auto) open popover with preventDefault does not close");
+
+ // togglepopover
+
+ promise_test(async function (t) {
+ assert_false(invokee.matches(":popover-open"));
+ invokerbutton.setAttribute("invokeaction", "togglepopover");
+ t.add_cleanup(() => invokerbutton.removeAttribute("invokeaction"));
+ await clickOn(invokerbutton);
+ t.add_cleanup(() => invokee.hidePopover());
+ assert_true(invokee.matches(":popover-open"));
+ }, "invoking (as togglepopover) closed popover opens");
+
+ promise_test(async function (t) {
+ assert_false(invokee.matches(":popover-open"));
+ invokerbutton.setAttribute("invokeaction", "tOgGlEpOpOvEr");
+ t.add_cleanup(() => invokerbutton.removeAttribute("invokeaction"));
+ await clickOn(invokerbutton);
+ t.add_cleanup(() => invokee.hidePopover());
+ assert_true(invokee.matches(":popover-open"));
+ }, "invoking (as togglepopover - case insensitive) closed popover opens");
+
+ promise_test(async function (t) {
+ assert_false(invokee.matches(":popover-open"));
+ invokerbutton.setAttribute("invokeaction", "togglepopover");
+ t.add_cleanup(() => invokerbutton.removeAttribute("invokeaction"));
+ invokee.addEventListener("invoke", (e) => e.preventDefault(), {
+ once: true,
+ });
+ await clickOn(invokerbutton);
+ t.add_cleanup(() => invokee.hidePopover());
+ assert_false(invokee.matches(":popover-open"));
+ }, "invoking (as togglepopover) closed popover with preventDefault does not open");
+
+ promise_test(async function (t) {
+ invokee.showPopover();
+ invokerbutton2.setAttribute("invokeaction", "togglepopover");
+ t.add_cleanup(() => invokerbutton2.removeAttribute("invokeaction"));
+ assert_true(invokee.matches(":popover-open"));
+ await clickOn(invokerbutton2);
+ assert_false(invokee.matches(":popover-open"));
+ }, "invoking (as togglepopover) open popover closes");
+
+ promise_test(async function (t) {
+ invokee.showPopover();
+ t.add_cleanup(() => invokee.hidePopover());
+ invokerbutton2.setAttribute("invokeaction", "togglepopover");
+ t.add_cleanup(() => invokerbutton2.removeAttribute("invokeaction"));
+ invokee.addEventListener("invoke", (e) => e.preventDefault(), {
+ once: true,
+ });
+ assert_true(invokee.matches(":popover-open"));
+ await clickOn(invokerbutton2);
+ assert_true(invokee.matches(":popover-open"));
+ }, "invoking (as togglepopover) open popover with preventDefault does not close");
+
+ // showpopover
+
+ promise_test(async function (t) {
+ invokerbutton.setAttribute("invokeaction", "showpopover");
+ t.add_cleanup(() => invokerbutton.removeAttribute("invokeaction"));
+ assert_false(invokee.matches(":popover-open"));
+ await clickOn(invokerbutton);
+ t.add_cleanup(() => invokee.hidePopover());
+ assert_true(invokee.matches(":popover-open"));
+ }, "invoking (as showpopover) closed popover opens");
+
+ promise_test(async function (t) {
+ invokerbutton.setAttribute("invokeaction", "sHoWpOpOvEr");
+ t.add_cleanup(() => invokerbutton.removeAttribute("invokeaction"));
+ assert_false(invokee.matches(":popover-open"));
+ await clickOn(invokerbutton);
+ t.add_cleanup(() => invokee.hidePopover());
+ assert_true(invokee.matches(":popover-open"));
+ }, "invoking (as showpopover - case insensitive) closed popover opens");
+
+ promise_test(async function (t) {
+ invokerbutton.setAttribute("invokeaction", "showpopover");
+ t.add_cleanup(() => invokerbutton.removeAttribute("invokeaction"));
+ invokee.showPopover();
+ assert_true(invokee.matches(":popover-open"));
+ await clickOn(invokerbutton);
+ t.add_cleanup(() => invokee.hidePopover());
+ assert_true(invokee.matches(":popover-open"));
+ }, "invoking (as showpopover) open popover is noop");
+
+ promise_test(async function (t) {
+ invokerbutton.setAttribute("invokeaction", "showpopover");
+ t.add_cleanup(() => invokerbutton.removeAttribute("invokeaction"));
+ assert_false(invokee.matches(":popover-open"));
+ invokee.addEventListener("invoke", (e) => e.preventDefault(), {
+ once: true,
+ });
+ await clickOn(invokerbutton);
+ t.add_cleanup(() => invokee.hidePopover());
+ assert_false(invokee.matches(":popover-open"));
+ }, "invoking (as showpopover) closed popover with preventDefault does not open");
+
+ // hidepopover
+
+ promise_test(async function (t) {
+ invokerbutton.setAttribute("invokeaction", "hidepopover");
+ t.add_cleanup(() => invokerbutton.removeAttribute("invokeaction"));
+ assert_false(invokee.matches(":popover-open"));
+ await clickOn(invokerbutton);
+ assert_false(invokee.matches(":popover-open"));
+ }, "invoking (as hidepopover) closed popover is noop");
+
+ promise_test(async function (t) {
+ invokerbutton2.setAttribute("invokeaction", "hidepopover");
+ t.add_cleanup(() => invokerbutton2.removeAttribute("invokeaction"));
+ invokee.showPopover();
+ assert_true(invokee.matches(":popover-open"));
+ await clickOn(invokerbutton2);
+ t.add_cleanup(() => invokee.hidePopover());
+ assert_false(invokee.matches(":popover-open"));
+ }, "invoking (as hidepopover) open popover closes");
+
+ promise_test(async function (t) {
+ invokerbutton2.setAttribute("invokeaction", "hIdEpOpOvEr");
+ t.add_cleanup(() => invokerbutton2.removeAttribute("invokeaction"));
+ invokee.showPopover();
+ assert_true(invokee.matches(":popover-open"));
+ await clickOn(invokerbutton2);
+ t.add_cleanup(() => invokee.hidePopover());
+ assert_false(invokee.matches(":popover-open"));
+ }, "invoking (as hidepopover - case insensitive) open popover closes");
+
+ promise_test(async function (t) {
+ invokerbutton2.setAttribute("invokeaction", "hidepopover");
+ t.add_cleanup(() => invokerbutton2.removeAttribute("invokeaction"));
+ invokee.showPopover();
+ t.add_cleanup(() => invokee.hidePopover());
+ assert_true(invokee.matches(":popover-open"));
+ invokee.addEventListener("invoke", (e) => e.preventDefault(), {
+ once: true,
+ });
+ await clickOn(invokerbutton2);
+ assert_true(invokee.matches(":popover-open"));
+ }, "invoking (as hidepopover) open popover with preventDefault does not close");
+</script>
diff --git a/tests/wpt/tests/html/semantics/popovers/popover-close-request.html b/tests/wpt/tests/html/semantics/popovers/popover-close-request.html
new file mode 100644
index 00000000000..830a40e0608
--- /dev/null
+++ b/tests/wpt/tests/html/semantics/popovers/popover-close-request.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Popover close request behavior</title>
+<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="/common/top-layer.js"></script>
+<script src="/close-watcher/resources/helpers.js"></script>
+
+<div popover id=p1>
+ Inside popover 1
+ <div popover id=p2>Inside popover 2</div>
+</div>
+
+<script>
+promise_test(async () => {
+ const popover1 = document.querySelector('#p1');
+ const popover2 = document.querySelector('#p2');
+
+ popover1.showPopover();
+
+ // Bless the opening of popover2, so it doesn't get grouped with popover1 by
+ // the close watcher infrastructure.
+ await blessTopLayer(popover1);
+ popover2.showPopover();
+
+ assert_true(popover1.matches(':popover-open'), "Starting: popover1 must be open");
+ assert_true(popover2.matches(':popover-open'), "Starting: popover2 must be open");
+
+ await sendCloseRequest();
+ assert_true(popover1.matches(':popover-open'), "After one close request, popover1 must be open");
+ assert_false(popover2.matches(':popover-open'), "After one close request, popover2 must be closed");
+
+ await sendCloseRequest();
+ assert_false(popover1.matches(':popover-open'), "After two close requests, popover1 must be closed");
+ assert_false(popover2.matches(':popover-open'), "After two close requests, popover2 must be closed");
+});
+</script>
diff --git a/tests/wpt/tests/html/semantics/popovers/popover-top-layer-combinations.html b/tests/wpt/tests/html/semantics/popovers/popover-top-layer-combinations.html
index c6fae283874..024794f5785 100644
--- a/tests/wpt/tests/html/semantics/popovers/popover-top-layer-combinations.html
+++ b/tests/wpt/tests/html/semantics/popovers/popover-top-layer-combinations.html
@@ -9,6 +9,7 @@
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-actions.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
+<script src="/common/top-layer.js"></script>
<script src="resources/popover-utils.js"></script>
<button id=visible>Visible button</button>
diff --git a/tests/wpt/tests/html/semantics/popovers/popover-top-layer-interactions.html b/tests/wpt/tests/html/semantics/popovers/popover-top-layer-interactions.html
index 95da47a5e20..6d050ed99bb 100644
--- a/tests/wpt/tests/html/semantics/popovers/popover-top-layer-interactions.html
+++ b/tests/wpt/tests/html/semantics/popovers/popover-top-layer-interactions.html
@@ -8,6 +8,7 @@
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
+<script src="/common/top-layer.js"></script>
<script src="resources/popover-utils.js"></script>
<body>
diff --git a/tests/wpt/tests/html/semantics/popovers/resources/popover-utils.js b/tests/wpt/tests/html/semantics/popovers/resources/popover-utils.js
index f11291e5c2f..bfc1f89ec10 100644
--- a/tests/wpt/tests/html/semantics/popovers/resources/popover-utils.js
+++ b/tests/wpt/tests/html/semantics/popovers/resources/popover-utils.js
@@ -46,22 +46,6 @@ async function sendEnter() {
function isElementVisible(el) {
return !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length);
}
-function isTopLayer(el) {
- // A bit of a hack. Just test a few properties of the ::backdrop pseudo
- // element that change when in the top layer.
- const properties = ['right','background'];
- const testEl = document.createElement('div');
- document.body.appendChild(testEl);
- const computedStyle = getComputedStyle(testEl, '::backdrop');
- const nonTopLayerValues = properties.map(p => computedStyle[p]);
- testEl.remove();
- for(let i=0;i<properties.length;++i) {
- if (getComputedStyle(el,'::backdrop')[properties[i]] !== nonTopLayerValues[i]) {
- return true;
- }
- }
- return false;
-}
async function finishAnimations(popover) {
popover.getAnimations({subtree: true}).forEach(animation => animation.finish());
await waitForRender();
@@ -95,19 +79,6 @@ async function mouseHover(element,hoverWaitTimeMs) {
assertMouseStillOver(element);
}
-async function blessTopLayer(visibleElement) {
- // The normal "bless" function doesn't work well when there are top layer
- // elements blocking clicks. Additionally, since the normal test_driver.bless
- // function just adds a button to the main document and clicks it, we can't
- // call that in the presence of open popovers, since that click will close them.
- const button = document.createElement('button');
- button.innerHTML = "Click me to activate";
- visibleElement.appendChild(button);
- let wait_click = new Promise(resolve => button.addEventListener("click", resolve, {once: true}));
- await test_driver.click(button);
- await wait_click;
- button.remove();
-}
// This is a "polyfill" of sorts for the `defaultopen` attribute.
// It can be called before window.load is complete, and it will
// show defaultopen popovers according to the rules previously part
diff --git a/tests/wpt/tests/idle-detection/WEB_FEATURES.yml b/tests/wpt/tests/idle-detection/WEB_FEATURES.yml
new file mode 100644
index 00000000000..1e208f268e3
--- /dev/null
+++ b/tests/wpt/tests/idle-detection/WEB_FEATURES.yml
@@ -0,0 +1,3 @@
+features:
+- name: idle-detection
+ files: "**"
diff --git a/tests/wpt/tests/infrastructure/metadata/infrastructure/webdriver/tests/test_load_file.py.ini b/tests/wpt/tests/infrastructure/metadata/infrastructure/webdriver/tests/test_load_file.py.ini
new file mode 100644
index 00000000000..7e6ef522c9b
--- /dev/null
+++ b/tests/wpt/tests/infrastructure/metadata/infrastructure/webdriver/tests/test_load_file.py.ini
@@ -0,0 +1,2 @@
+disabled:
+ if product == "firefox": @True
diff --git a/tests/wpt/tests/interfaces/invokers.tentative.idl b/tests/wpt/tests/interfaces/invokers.tentative.idl
index 67e2eb4ce19..62f7398b827 100644
--- a/tests/wpt/tests/interfaces/invokers.tentative.idl
+++ b/tests/wpt/tests/interfaces/invokers.tentative.idl
@@ -11,5 +11,5 @@ interface InvokeEvent : Event {
dictionary InvokeEventInit : EventInit {
Element? invoker = null;
- DOMString action = "";
+ DOMString action = "auto";
};
diff --git a/tests/wpt/tests/jpegxl/3x3_jpeg_recompression-ref.html b/tests/wpt/tests/jpegxl/3x3_jpeg_recompression-ref.html
new file mode 100644
index 00000000000..070243d6a7e
--- /dev/null
+++ b/tests/wpt/tests/jpegxl/3x3_jpeg_recompression-ref.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<title>JPEG XL test reference</title>
+
+<img src="./resources/3x3_jpeg_recompression.png">
diff --git a/tests/wpt/tests/jpegxl/3x3_jpeg_recompression.html b/tests/wpt/tests/jpegxl/3x3_jpeg_recompression.html
new file mode 100644
index 00000000000..f28fca8fdce
--- /dev/null
+++ b/tests/wpt/tests/jpegxl/3x3_jpeg_recompression.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<title>JPEG XL test</title>
+<meta name=fuzzy content="0-1;0-9">
+<link rel="help" href="https://jpeg.org/jpegxl/">
+<link rel="match" href="3x3_jpeg_recompression-ref.html">
+<meta name="assert" content="JPEG XL image is rendered correctly">
+
+<img src="./resources/3x3_jpeg_recompression.jxl">
diff --git a/tests/wpt/tests/jpegxl/3x3_srgb_lossless-ref.html b/tests/wpt/tests/jpegxl/3x3_srgb_lossless-ref.html
new file mode 100644
index 00000000000..1bb50832409
--- /dev/null
+++ b/tests/wpt/tests/jpegxl/3x3_srgb_lossless-ref.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<title>JPEG XL test reference</title>
+
+<img src="./resources/3x3_srgb_lossless.png">
diff --git a/tests/wpt/tests/jpegxl/3x3_srgb_lossless.html b/tests/wpt/tests/jpegxl/3x3_srgb_lossless.html
new file mode 100644
index 00000000000..589f11c68c4
--- /dev/null
+++ b/tests/wpt/tests/jpegxl/3x3_srgb_lossless.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<title>JPEG XL test</title>
+<meta name=fuzzy content="0-4;0-9">
+<link rel="help" href="https://jpeg.org/jpegxl/">
+<link rel="match" href="3x3_srgb_lossless-ref.html">
+<meta name="assert" content="JPEG XL image is rendered correctly">
+
+<img src="./resources/3x3_srgb_lossless.jxl">
diff --git a/tests/wpt/tests/jpegxl/srgb-ref.html b/tests/wpt/tests/jpegxl/3x3_srgb_lossy-ref.html
index 634567e4303..a5e95baba3b 100644
--- a/tests/wpt/tests/jpegxl/srgb-ref.html
+++ b/tests/wpt/tests/jpegxl/3x3_srgb_lossy-ref.html
@@ -1,4 +1,4 @@
<!DOCTYPE html>
<title>JPEG XL test reference</title>
-<img src="./resources/3x3.png">
+<img src="./resources/3x3_srgb_lossy.png">
diff --git a/tests/wpt/tests/jpegxl/srgb.html b/tests/wpt/tests/jpegxl/3x3_srgb_lossy.html
index 9d131787ec3..3a92b2b7301 100644
--- a/tests/wpt/tests/jpegxl/srgb.html
+++ b/tests/wpt/tests/jpegxl/3x3_srgb_lossy.html
@@ -1,7 +1,8 @@
<!DOCTYPE html>
<title>JPEG XL test</title>
+<meta name=fuzzy content="0-10;0-9">
<link rel="help" href="https://jpeg.org/jpegxl/">
-<link rel="match" href="srgb-ref.html">
+<link rel="match" href="3x3_srgb_lossy-ref.html">
<meta name="assert" content="JPEG XL image is rendered correctly">
-<img src="./resources/3x3_srgb.jxl">
+<img src="./resources/3x3_srgb_lossy.jxl">
diff --git a/tests/wpt/tests/jpegxl/3x3a_srgb_lossless-ref.html b/tests/wpt/tests/jpegxl/3x3a_srgb_lossless-ref.html
new file mode 100644
index 00000000000..75d8ba7452e
--- /dev/null
+++ b/tests/wpt/tests/jpegxl/3x3a_srgb_lossless-ref.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<title>JPEG XL test reference</title>
+
+<img src="./resources/3x3a_srgb_lossless.png">
diff --git a/tests/wpt/tests/jpegxl/3x3a_srgb_lossless.html b/tests/wpt/tests/jpegxl/3x3a_srgb_lossless.html
new file mode 100644
index 00000000000..1de61a5ba27
--- /dev/null
+++ b/tests/wpt/tests/jpegxl/3x3a_srgb_lossless.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<title>JPEG XL test</title>
+<meta name=fuzzy content="0-4;0-9">
+<link rel="help" href="https://jpeg.org/jpegxl/">
+<link rel="match" href="3x3a_srgb_lossless-ref.html">
+<meta name="assert" content="JPEG XL image is rendered correctly">
+
+<img src="./resources/3x3a_srgb_lossless.jxl">
diff --git a/tests/wpt/tests/jpegxl/3x3a_srgb_lossy-ref.html b/tests/wpt/tests/jpegxl/3x3a_srgb_lossy-ref.html
new file mode 100644
index 00000000000..3a1c22e8a27
--- /dev/null
+++ b/tests/wpt/tests/jpegxl/3x3a_srgb_lossy-ref.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<title>JPEG XL test reference</title>
+
+<img src="./resources/3x3a_srgb_lossy.png">
diff --git a/tests/wpt/tests/jpegxl/3x3a_srgb_lossy.html b/tests/wpt/tests/jpegxl/3x3a_srgb_lossy.html
new file mode 100644
index 00000000000..59583a11a9a
--- /dev/null
+++ b/tests/wpt/tests/jpegxl/3x3a_srgb_lossy.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<title>JPEG XL test</title>
+<meta name=fuzzy content="0-10;0-9">
+<link rel="help" href="https://jpeg.org/jpegxl/">
+<link rel="match" href="3x3a_srgb_lossy-ref.html">
+<meta name="assert" content="JPEG XL image is rendered correctly">
+
+<img src="./resources/3x3a_srgb_lossy.jxl">
diff --git a/tests/wpt/tests/jpegxl/resources/3x3.png b/tests/wpt/tests/jpegxl/resources/3x3.png
deleted file mode 100644
index 96f86420a5f..00000000000
--- a/tests/wpt/tests/jpegxl/resources/3x3.png
+++ /dev/null
Binary files differ
diff --git a/tests/wpt/tests/jpegxl/resources/3x3_jpeg_recompression.jxl b/tests/wpt/tests/jpegxl/resources/3x3_jpeg_recompression.jxl
new file mode 100644
index 00000000000..deee4257ff6
--- /dev/null
+++ b/tests/wpt/tests/jpegxl/resources/3x3_jpeg_recompression.jxl
Binary files differ
diff --git a/tests/wpt/tests/jpegxl/resources/3x3_jpeg_recompression.png b/tests/wpt/tests/jpegxl/resources/3x3_jpeg_recompression.png
new file mode 100644
index 00000000000..b147cb57bd8
--- /dev/null
+++ b/tests/wpt/tests/jpegxl/resources/3x3_jpeg_recompression.png
Binary files differ
diff --git a/tests/wpt/tests/jpegxl/resources/3x3_srgb.jxl b/tests/wpt/tests/jpegxl/resources/3x3_srgb.jxl
deleted file mode 100644
index 5e52b33641e..00000000000
--- a/tests/wpt/tests/jpegxl/resources/3x3_srgb.jxl
+++ /dev/null
Binary files differ
diff --git a/tests/wpt/tests/jpegxl/resources/3x3_srgb_lossless.jxl b/tests/wpt/tests/jpegxl/resources/3x3_srgb_lossless.jxl
new file mode 100644
index 00000000000..bb9cf0bb2e4
--- /dev/null
+++ b/tests/wpt/tests/jpegxl/resources/3x3_srgb_lossless.jxl
Binary files differ
diff --git a/tests/wpt/tests/jpegxl/resources/3x3_srgb_lossless.png b/tests/wpt/tests/jpegxl/resources/3x3_srgb_lossless.png
new file mode 100644
index 00000000000..f314145a139
--- /dev/null
+++ b/tests/wpt/tests/jpegxl/resources/3x3_srgb_lossless.png
Binary files differ
diff --git a/tests/wpt/tests/jpegxl/resources/3x3_srgb_lossy.jxl b/tests/wpt/tests/jpegxl/resources/3x3_srgb_lossy.jxl
new file mode 100644
index 00000000000..a2d7a898e15
--- /dev/null
+++ b/tests/wpt/tests/jpegxl/resources/3x3_srgb_lossy.jxl
Binary files differ
diff --git a/tests/wpt/tests/jpegxl/resources/3x3_srgb_lossy.png b/tests/wpt/tests/jpegxl/resources/3x3_srgb_lossy.png
new file mode 100644
index 00000000000..ad5ef8117f6
--- /dev/null
+++ b/tests/wpt/tests/jpegxl/resources/3x3_srgb_lossy.png
Binary files differ
diff --git a/tests/wpt/tests/jpegxl/resources/3x3a_srgb_lossless.jxl b/tests/wpt/tests/jpegxl/resources/3x3a_srgb_lossless.jxl
new file mode 100644
index 00000000000..6bbb43d8e72
--- /dev/null
+++ b/tests/wpt/tests/jpegxl/resources/3x3a_srgb_lossless.jxl
Binary files differ
diff --git a/tests/wpt/tests/jpegxl/resources/3x3a_srgb_lossless.png b/tests/wpt/tests/jpegxl/resources/3x3a_srgb_lossless.png
new file mode 100644
index 00000000000..3c5f9c4e6b1
--- /dev/null
+++ b/tests/wpt/tests/jpegxl/resources/3x3a_srgb_lossless.png
Binary files differ
diff --git a/tests/wpt/tests/jpegxl/resources/3x3a_srgb_lossy.jxl b/tests/wpt/tests/jpegxl/resources/3x3a_srgb_lossy.jxl
new file mode 100644
index 00000000000..0a4e952e3b8
--- /dev/null
+++ b/tests/wpt/tests/jpegxl/resources/3x3a_srgb_lossy.jxl
Binary files differ
diff --git a/tests/wpt/tests/jpegxl/resources/3x3a_srgb_lossy.png b/tests/wpt/tests/jpegxl/resources/3x3a_srgb_lossy.png
new file mode 100644
index 00000000000..885c5d03592
--- /dev/null
+++ b/tests/wpt/tests/jpegxl/resources/3x3a_srgb_lossy.png
Binary files differ
diff --git a/tests/wpt/tests/jpegxl/resources/generate_resources.sh b/tests/wpt/tests/jpegxl/resources/generate_resources.sh
new file mode 100755
index 00000000000..359b2afd9ea
--- /dev/null
+++ b/tests/wpt/tests/jpegxl/resources/generate_resources.sh
@@ -0,0 +1,76 @@
+#!/bin/bash
+# This generates the png and jxl images needed.
+
+# Function to check if a command exists
+command_exists() {
+ command -v "$1" &> /dev/null
+}
+
+# Function to convert and compress an image
+convert_and_compress() {
+ local input_image=$1
+ local base_name=$2
+ local color_space=$3
+
+ cjxl "$input_image" temp.jxl -d 0
+ djxl temp.jxl "${base_name}_${color_space}_lossless.png"
+ cjxl "${base_name}_${color_space}_lossless.png" "${base_name}_${color_space}_lossy.jxl" -d 0.0001 -e 7
+ djxl "${base_name}_${color_space}_lossy.jxl" "${base_name}_${color_space}_lossy.png"
+ cjxl "${base_name}_${color_space}_lossless.png" "${base_name}_${color_space}_lossless.jxl" -d 0
+}
+
+# Check for required tools
+for tool in convert cjxl djxl; do
+ if ! command_exists "$tool"; then
+ echo "$tool could not be found. Please install it and run the script again."
+ exit 1
+ fi
+done
+
+# Create a 3x3 transparent image
+convert -size 3x3 xc:none 3x3a.png
+
+# Draw colors with alpha values
+convert 3x3a.png \
+-fill "rgba(255,0,0,0.5)" -draw "point 0,0" \
+-fill "rgba(0,255,0,0.5)" -draw "point 1,0" \
+-fill "rgba(0,0,255,0.5)" -draw "point 2,0" \
+-fill "rgba(128,64,64,0.5)" -draw "point 0,1" \
+-fill "rgba(64,128,64,0.5)" -draw "point 1,1" \
+-fill "rgba(64,64,128,0.5)" -draw "point 2,1" \
+-fill "rgba(255,255,255,0.5)" -draw "point 0,2" \
+-fill "rgba(128,128,128,0.5)" -draw "point 1,2" \
+-fill "rgba(0,0,0,0.5)" -draw "point 2,2" \
+3x3a.png
+
+# Generate initial image with alpha values
+generate_image 3x3a.png
+
+# Generate a version without alpha channel
+convert 3x3a.png -alpha off 3x3.png
+
+# Define color spaces
+# TODO(firsching): add "RGB_D65_202_Rel_PeQ" and "RGB_D65_202_Rel_HLG" as color spaces here
+color_spaces=("srgb")
+
+# Loop through color spaces and convert/compress images
+for color_space in "${color_spaces[@]}"; do
+ convert_and_compress 3x3.png "3x3" "$color_space"
+ convert_and_compress 3x3a.png "3x3a" "$color_space"
+done
+
+convert 3x3.png -quality 70 3x3.jpg
+# lossless recompression
+cjxl 3x3.jpg 3x3_jpeg_recompression.jxl
+# checking that it was actually byte exact
+djxl 3x3_jpeg_recompression.jxl 3x3_recovered.jpg
+diff 3x3.jpg 3x3_recovered.jpg
+if [ $? -ne 0 ]; then
+ echo "The recovery of the recompressed jpg failed: 3x3.png and 3x3_recovered.jpg differ"
+ exit 1
+fi
+# generate reference png
+djxl 3x3_jpeg_recompression.jxl 3x3_jpeg_recompression.png
+
+# Cleanup temporary file
+rm -f temp.jxl 3x3.png 3x3a.png 3x3.jpg 3x3_recovered.jpg
diff --git a/tests/wpt/tests/lint.ignore b/tests/wpt/tests/lint.ignore
index 247d2950d55..5a16051bbd4 100644
--- a/tests/wpt/tests/lint.ignore
+++ b/tests/wpt/tests/lint.ignore
@@ -20,6 +20,7 @@ TRAILING WHITESPACE: html/syntax/xmldecl/support/no-version-or-space-or-trailing
TRAILING WHITESPACE, INDENT TABS, CR AT EOL: *.adts
TRAILING WHITESPACE, INDENT TABS, CR AT EOL: *.pdf
TRAILING WHITESPACE, INDENT TABS, CR AT EOL: *.jpg
+TRAILING WHITESPACE, INDENT TABS, CR AT EOL: *.jxl
TRAILING WHITESPACE, INDENT TABS, CR AT EOL: *.png
TRAILING WHITESPACE, INDENT TABS, CR AT EOL: *.gif
TRAILING WHITESPACE, INDENT TABS, CR AT EOL: *.wav
@@ -146,7 +147,6 @@ SET TIMEOUT: conformance-checkers/*
SET TIMEOUT: content-security-policy/*
SET TIMEOUT: css/compositing/opacity-and-transform-animation-crash.html
SET TIMEOUT: css/css-contain/contain-body-overflow-002.html
-SET TIMEOUT: css/css-lists/dynamic-counters-crash.html
SET TIMEOUT: css/css-display/display-contents-shadow-dom-1.html
SET TIMEOUT: css/CSS2/normal-flow/crashtests/block-in-inline-ax-crash.html
SET TIMEOUT: css/selectors/selector-placeholder-shown-type-change-001.html
@@ -311,8 +311,6 @@ GENERATE_TESTS: dom/ranges/Range-selectNode.html
GENERATE_TESTS: dom/ranges/Range-set.html
GENERATE_TESTS: dom/traversal/TreeWalker.html
GENERATE_TESTS: domparsing/createContextualFragment.html
-GENERATE_TESTS: domxpath/001.html
-GENERATE_TESTS: domxpath/002.html
GENERATE_TESTS: mediacapture-image/MediaStreamTrack-applyConstraints-reject.https.html
GENERATE_TESTS: mediacapture-image/MediaStreamTrack-getCapabilities.https.html
GENERATE_TESTS: mediacapture-image/MediaStreamTrack-getConstraints.https.html
@@ -375,6 +373,7 @@ SET TIMEOUT: speculation-rules/prerender/resources/media-autoplay-attribute.html
SET TIMEOUT: speculation-rules/prerender/resources/media-play.html
SET TIMEOUT: html/browsers/browsing-the-web/back-forward-cache/timers.html
SET TIMEOUT: dom/abort/crashtests/timeout-close.html
+SET TIMEOUT: storage-access-api/storage-access-beyond-cookies.locks.tentative.sub.https.window.js
# setTimeout use in reftests
SET TIMEOUT: acid/acid3/test.html
diff --git a/tests/wpt/tests/long-animation-frame/tentative/loaf-stream-source-location.html b/tests/wpt/tests/long-animation-frame/tentative/loaf-stream-source-location.html
new file mode 100644
index 00000000000..3b6b2b31608
--- /dev/null
+++ b/tests/wpt/tests/long-animation-frame/tentative/loaf-stream-source-location.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<meta charset=utf-8>
+<title>Long Animation Frame Timing: source location extraction for streams</title>
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/utils.js"></script>
+
+<body>
+<h1>Long Animation Frame: source location extraction for streams</h1>
+<div id="log"></div>
+<script>
+
+const source_location_regex = /^([^@]+\@)?https?\:\/\/[^\/]+[^\:]+\:\d*$/;
+
+promise_test(async t => {
+ const scriptLocation = new URL("resources/stream-promise-generates-loaf.js", location.href);
+ const [entry, script] = await expect_long_frame_with_script(() => {
+ const scriptElement = document.createElement("script");
+ scriptElement.src = scriptLocation;
+ document.body.appendChild(scriptElement);
+ }, script => script.name === "StreamPromise.resolve.then", t);
+
+ assert_true(script.sourceLocation?.includes("stream-promise-generates-loaf.js"));
+}, "Source location should be extracted for stream promises");
+
+</script>
+</body>
diff --git a/tests/wpt/tests/long-animation-frame/tentative/resources/stream-promise-generates-loaf.js b/tests/wpt/tests/long-animation-frame/tentative/resources/stream-promise-generates-loaf.js
new file mode 100644
index 00000000000..35e7920bb20
--- /dev/null
+++ b/tests/wpt/tests/long-animation-frame/tentative/resources/stream-promise-generates-loaf.js
@@ -0,0 +1,12 @@
+(async() => {
+ const response = await fetch("/common/dummy.xml");
+ const {readable, writable} = new TransformStream({
+ start() {},
+ transform() {
+ const deadline = performance.now() + 360;
+ while (performance.now() < deadline) {}
+ }
+ });
+ response.body.pipeTo(writable);
+ await readable.getReader().read();
+})();
diff --git a/tests/wpt/tests/magnetometer/Magnetometer-iframe-access.https.html b/tests/wpt/tests/magnetometer/Magnetometer-iframe-access.https.html
index 3dc90e3dd7f..7aabd0eb61b 100644
--- a/tests/wpt/tests/magnetometer/Magnetometer-iframe-access.https.html
+++ b/tests/wpt/tests/magnetometer/Magnetometer-iframe-access.https.html
@@ -5,12 +5,15 @@
<link rel="help" href="https://www.w3.org/TR/magnetometer/">
<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="/generic-sensor/resources/generic-sensor-helpers.js"></script>
<script src="/generic-sensor/generic-sensor-iframe-tests.sub.js"></script>
<script src="/generic-sensor/generic-sensor-feature-policy-test.sub.js"></script>
+<script src="resources/sensor-data.js"></script>
<div id="log"></div>
<script>
-run_generic_sensor_iframe_tests('Magnetometer');
-run_generic_sensor_iframe_tests('UncalibratedMagnetometer');
+run_generic_sensor_iframe_tests(kMagnetometerSensorData, kMagnetometerReadings);
+run_generic_sensor_iframe_tests(kUncalibratedMagnetometerSensorData, kMagnetometerReadings);
</script>
diff --git a/tests/wpt/tests/magnetometer/Magnetometer.https.html b/tests/wpt/tests/magnetometer/Magnetometer.https.html
index 0cc443784be..6beb534509d 100644
--- a/tests/wpt/tests/magnetometer/Magnetometer.https.html
+++ b/tests/wpt/tests/magnetometer/Magnetometer.https.html
@@ -6,34 +6,17 @@
<link rel="help" href="https://www.w3.org/TR/magnetometer/">
<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="/page-visibility/resources/window_state_context.js"></script>
<script src="/generic-sensor/resources/generic-sensor-helpers.js"></script>
<script src="/generic-sensor/generic-sensor-tests.js"></script>
+<script src="resources/sensor-data.js"></script>
<script>
'use strict';
-const kReadings = {
- readings: [
- [-19.2, 12.1, -44.3]
- ],
- expectedReadings: [
- [-19.2, 12.1, -44.3]
- ],
- expectedRemappedReadings: [
- [-12.1, -19.2, -44.3]
- ]
-};
-
-runGenericSensorTests(
- 'Magnetometer',
- kReadings,
- verifyXyzSensorReading,
- ['magnetometer']);
-
-runGenericSensorTests(
- 'UncalibratedMagnetometer',
- kReadings,
- verifyXyzSensorReading,
- ['magnetometer']);
+runGenericSensorTests(kMagnetometerSensorData, kMagnetometerReadings);
+runGenericSensorTests(kUncalibratedMagnetometerSensorData, kMagnetometerReadings);
</script>
diff --git a/tests/wpt/tests/magnetometer/resources/sensor-data.js b/tests/wpt/tests/magnetometer/resources/sensor-data.js
new file mode 100644
index 00000000000..32c2b1e2895
--- /dev/null
+++ b/tests/wpt/tests/magnetometer/resources/sensor-data.js
@@ -0,0 +1,21 @@
+'use strict';
+
+const kMagnetometerSensorData = {
+ sensorName: 'Magnetometer',
+ permissionName: 'magnetometer',
+ testDriverName: 'magnetometer',
+ featurePolicyNames: ['magnetometer']
+};
+
+const kUncalibratedMagnetometerSensorData = {
+ sensorName: 'UncalibratedMagnetometer',
+ permissionName: 'magnetometer',
+ testDriverName: 'magnetometer',
+ featurePolicyNames: ['magnetometer']
+};
+
+const kMagnetometerReadings = {
+ readings: [{x: -19.2, y: 12.1, z: -44.3}],
+ expectedReadings: [{x: -19.2, y: 12.1, z: -44.3}],
+ expectedRemappedReadings: [{x: -12.1, y: -19.2, z: -44.3}]
+};
diff --git a/tests/wpt/tests/mediacapture-extensions/MediaStreamTrack-video-stats.https.html b/tests/wpt/tests/mediacapture-extensions/MediaStreamTrack-video-stats.https.html
index 6901ed84e39..f1b6a2074a4 100644
--- a/tests/wpt/tests/mediacapture-extensions/MediaStreamTrack-video-stats.https.html
+++ b/tests/wpt/tests/mediacapture-extensions/MediaStreamTrack-video-stats.https.html
@@ -326,8 +326,8 @@ promise_test(async t => {
const [track] = stream.getTracks();
t.add_cleanup(() => track.stop());
- assert_throws_dom('NotSupportedError', () => track.stats);
-}, `track.stats throws on audio tracks`);
+ assert_equals(track.stats, null);
+}, `track.stats is null on audio tracks`);
promise_test(async t => {
const canvas = document.createElement('canvas');
@@ -335,8 +335,8 @@ promise_test(async t => {
const [track] = stream.getTracks();
t.add_cleanup(() => track.stop());
- assert_throws_dom('NotSupportedError', () => track.stats);
-}, `track.stats throws on non-device tracks, such as canvas`);
+ assert_equals(track.stats, null);
+}, `track.stats is null on non-device tracks, such as canvas`);
promise_test(async t => {
// getDisplayMedia() requires inducing a user gesture.
diff --git a/tests/wpt/tests/orientation-sensor/AbsoluteOrientationSensor-iframe-access.https.html b/tests/wpt/tests/orientation-sensor/AbsoluteOrientationSensor-iframe-access.https.html
index e99b5c6365d..4831b5e7192 100644
--- a/tests/wpt/tests/orientation-sensor/AbsoluteOrientationSensor-iframe-access.https.html
+++ b/tests/wpt/tests/orientation-sensor/AbsoluteOrientationSensor-iframe-access.https.html
@@ -5,11 +5,14 @@
<link rel="help" href="https://www.w3.org/TR/orientation-sensor/">
<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="/generic-sensor/resources/generic-sensor-helpers.js"></script>
<script src="/generic-sensor/generic-sensor-iframe-tests.sub.js"></script>
<script src="/generic-sensor/generic-sensor-feature-policy-test.sub.js"></script>
+<script src="resources/sensor-data.js"></script>
<div id="log"></div>
<script>
-run_generic_sensor_iframe_tests('AbsoluteOrientationSensor');
+run_generic_sensor_iframe_tests(kAbsoluteOrientationSensorData, kOrientationReadings);
</script>
diff --git a/tests/wpt/tests/orientation-sensor/AbsoluteOrientationSensor.https.html b/tests/wpt/tests/orientation-sensor/AbsoluteOrientationSensor.https.html
index e6f5dd91383..4c516da1451 100644
--- a/tests/wpt/tests/orientation-sensor/AbsoluteOrientationSensor.https.html
+++ b/tests/wpt/tests/orientation-sensor/AbsoluteOrientationSensor.https.html
@@ -7,17 +7,19 @@
<link rel="help" href="https://w3c.github.io/sensors/">
<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="/page-visibility/resources/window_state_context.js"></script>
<script src="/generic-sensor/resources/generic-sensor-helpers.js"></script>
<script src="/generic-sensor/generic-sensor-tests.js"></script>
<script src="/orientation-sensor/orientation-sensor-tests.js"></script>
+<script src="resources/sensor-data.js"></script>
<script>
-runGenericSensorTests(
- 'AbsoluteOrientationSensor',
- kReadings,
- verifyQuatSensorReading,
- ['accelerometer', 'gyroscope', 'magnetometer']);
+'use strict';
-runOrientationSensorTests('AbsoluteOrientationSensor');
+runGenericSensorTests(kAbsoluteOrientationSensorData, kOrientationReadings);
+
+runOrientationSensorTests(kAbsoluteOrientationSensorData, kOrientationReadings);
</script>
diff --git a/tests/wpt/tests/orientation-sensor/RelativeOrientationSensor-iframe-access.https.html b/tests/wpt/tests/orientation-sensor/RelativeOrientationSensor-iframe-access.https.html
index 5d30534841b..fe995e2d1b9 100644
--- a/tests/wpt/tests/orientation-sensor/RelativeOrientationSensor-iframe-access.https.html
+++ b/tests/wpt/tests/orientation-sensor/RelativeOrientationSensor-iframe-access.https.html
@@ -5,11 +5,14 @@
<link rel="help" href="https://www.w3.org/TR/orientation-sensor/">
<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="/generic-sensor/resources/generic-sensor-helpers.js"></script>
<script src="/generic-sensor/generic-sensor-iframe-tests.sub.js"></script>
<script src="/generic-sensor/generic-sensor-feature-policy-test.sub.js"></script>
+<script src="resources/sensor-data.js"></script>
<div id="log"></div>
<script>
-run_generic_sensor_iframe_tests('RelativeOrientationSensor');
+run_generic_sensor_iframe_tests(kRelativeOrientationSensorData, kOrientationReadings);
</script>
diff --git a/tests/wpt/tests/orientation-sensor/RelativeOrientationSensor.https.html b/tests/wpt/tests/orientation-sensor/RelativeOrientationSensor.https.html
index 499e7df8cea..35dc8c31113 100644
--- a/tests/wpt/tests/orientation-sensor/RelativeOrientationSensor.https.html
+++ b/tests/wpt/tests/orientation-sensor/RelativeOrientationSensor.https.html
@@ -7,17 +7,19 @@
<link rel="help" href="https://w3c.github.io/sensors/">
<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="/page-visibility/resources/window_state_context.js"></script>
<script src="/generic-sensor/resources/generic-sensor-helpers.js"></script>
<script src="/generic-sensor/generic-sensor-tests.js"></script>
<script src="/orientation-sensor/orientation-sensor-tests.js"></script>
+<script src="resources/sensor-data.js"></script>
<script>
-runGenericSensorTests(
- 'RelativeOrientationSensor',
- kReadings,
- verifyQuatSensorReading,
- ['accelerometer', 'gyroscope']);
+'use strict';
-runOrientationSensorTests('RelativeOrientationSensor');
+runGenericSensorTests(kRelativeOrientationSensorData, kOrientationReadings);
+
+runOrientationSensorTests(kRelativeOrientationSensorData, kOrientationReadings);
</script>
diff --git a/tests/wpt/tests/orientation-sensor/orientation-sensor-tests.js b/tests/wpt/tests/orientation-sensor/orientation-sensor-tests.js
index 88fd432d470..d69fa3e54cd 100644
--- a/tests/wpt/tests/orientation-sensor/orientation-sensor-tests.js
+++ b/tests/wpt/tests/orientation-sensor/orientation-sensor-tests.js
@@ -1,89 +1,104 @@
'use strict';
-const kDefaultReading = [
- [ 1, 0, 0, 0 ] // 180 degrees around X axis.
-];
-const kRotationMatrix = [1, 0, 0, 0,
- 0, -1, 0, 0,
- 0, 0, -1, 0,
- 0, 0, 0, 1];
-const kReadings = {
- readings: kDefaultReading,
- expectedReadings: kDefaultReading,
- expectedRemappedReadings: [
- // For 'orientation.angle == 270', which is set for tests at
- // at SensorProxy::GetScreenOrientationAngle().
- [-0.707107, 0.707107, 0, 0]
- ]
-};
-
-async function checkQuaternion(t, sensorType) {
+async function checkQuaternion(
+ t, sensorType, testDriverName, permissionName, readings) {
+ await test_driver.set_permission({name: permissionName}, 'granted');
+ await test_driver.create_virtual_sensor(testDriverName);
const sensor = new sensorType();
- const eventWatcher = new EventWatcher(t, sensor, ["reading", "error"]);
+ t.add_cleanup(async () => {
+ sensor.stop();
+ await test_driver.remove_virtual_sensor(testDriverName);
+ });
+ const sensorWatcher =
+ new EventWatcher(t, sensor, ['activate', 'reading', 'error']);
sensor.start();
- await eventWatcher.wait_for("reading");
- assert_equals(sensor.quaternion.length, 4);
- assert_true(sensor.quaternion instanceof Array);
- sensor.stop();
+ await sensorWatcher.wait_for('activate');
+ await Promise.all([
+ test_driver.update_virtual_sensor(testDriverName, readings.next().value),
+ sensorWatcher.wait_for('reading')
+ ]);
+ assert_equals(sensor.quaternion.length, 4, 'Quaternion length must be 4');
+ assert_true(
+ sensor.quaternion instanceof Array, 'Quaternion is must be array');
};
-async function checkPopulateMatrix(t, sensorProvider, sensorType) {
+async function checkPopulateMatrix(
+ t, sensorProvider, sensorType, testDriverName, permissionName, readings) {
+ await test_driver.set_permission({name: permissionName}, 'granted');
+ await test_driver.create_virtual_sensor(testDriverName);
const sensor = new sensorType();
- const eventWatcher = new EventWatcher(t, sensor, ["reading", "error"]);
+ t.add_cleanup(async () => {
+ sensor.stop();
+ await test_driver.remove_virtual_sensor(testDriverName);
+ });
+ const sensorWatcher =
+ new EventWatcher(t, sensor, ['activate', 'reading', 'error']);
// Throws with insufficient buffer space.
- assert_throws_js(TypeError,
- () => sensor.populateMatrix(new Float32Array(15)));
+ assert_throws_js(
+ TypeError, () => sensor.populateMatrix(new Float32Array(15)));
// Throws if no orientation data available.
- assert_throws_dom('NotReadableError',
- () => sensor.populateMatrix(new Float32Array(16)));
+ assert_throws_dom(
+ 'NotReadableError', () => sensor.populateMatrix(new Float32Array(16)));
// Throws if passed SharedArrayBuffer view.
- assert_throws_js(TypeError,
- // See https://github.com/whatwg/html/issues/5380 for why not `new SharedArrayBuffer()`
- // WebAssembly.Memory's size is in multiples of 64 KiB
- () => sensor.populateMatrix(new Float32Array(new WebAssembly.Memory({ shared:true, initial:1, maximum:1 }).buffer)));
+ assert_throws_js(
+ TypeError,
+ // See https://github.com/whatwg/html/issues/5380 for why not `new
+ // SharedArrayBuffer()` WebAssembly.Memory's size is in multiples of 64KiB
+ () => sensor.populateMatrix(new Float32Array(
+ new WebAssembly.Memory({shared: true, initial: 1, maximum: 1})
+ .buffer)));
sensor.start();
+ await sensorWatcher.wait_for('activate');
- const mockSensor = await sensorProvider.getCreatedSensor(sensorType.name);
- await mockSensor.setSensorReading(kDefaultReading);
-
- await eventWatcher.wait_for("reading");
+ await Promise.all([
+ test_driver.update_virtual_sensor(testDriverName, readings.next().value),
+ sensorWatcher.wait_for('reading')
+ ]);
// Works for all supported types.
const rotationMatrix32 = new Float32Array(16);
sensor.populateMatrix(rotationMatrix32);
- assert_array_equals(rotationMatrix32, kRotationMatrix);
+ assert_array_approx_equals(rotationMatrix32, kRotationMatrix, kEpsilon);
let rotationMatrix64 = new Float64Array(16);
sensor.populateMatrix(rotationMatrix64);
- assert_array_equals(rotationMatrix64, kRotationMatrix);
+ assert_array_approx_equals(rotationMatrix64, kRotationMatrix, kEpsilon);
let rotationDOMMatrix = new DOMMatrix();
sensor.populateMatrix(rotationDOMMatrix);
- assert_array_equals(rotationDOMMatrix.toFloat64Array(), kRotationMatrix);
+ assert_array_approx_equals(
+ rotationDOMMatrix.toFloat64Array(), kRotationMatrix, kEpsilon);
// Sets every matrix element.
rotationMatrix64.fill(123);
sensor.populateMatrix(rotationMatrix64);
- assert_array_equals(rotationMatrix64, kRotationMatrix);
-
- sensor.stop();
+ assert_array_approx_equals(rotationMatrix64, kRotationMatrix, kEpsilon);
}
-function runOrientationSensorTests(sensorName) {
+function runOrientationSensorTests(sensorData, readingData) {
+ validate_sensor_data(sensorData);
+ validate_reading_data(readingData);
+
+ const {sensorName, permissionName, testDriverName} = sensorData;
const sensorType = self[sensorName];
- sensor_test(async t => {
- assert_true(sensorName in self);
- return checkQuaternion(t, sensorType);
+ const readings = new RingBuffer(readingData.readings);
+
+ promise_test(async t => {
+ assert_implements(sensorName in self, `${sensorName} is not supported.`);
+ return checkQuaternion(
+ t, sensorType, testDriverName, permissionName, readings);
}, `${sensorName}.quaternion return a four-element FrozenArray.`);
- sensor_test(async (t, sensorProvider) => {
- assert_true(sensorName in self);
- return checkPopulateMatrix(t, sensorProvider, sensorType);
+ promise_test(async (t, sensorProvider) => {
+ assert_implements(sensorName in self, `${sensorName} is not supported.`);
+ return checkPopulateMatrix(
+ t, sensorProvider, sensorType, testDriverName, permissionName,
+ readings);
}, `${sensorName}.populateMatrix() method works correctly.`);
}
diff --git a/tests/wpt/tests/orientation-sensor/resources/sensor-data.js b/tests/wpt/tests/orientation-sensor/resources/sensor-data.js
new file mode 100644
index 00000000000..d0b280fa6c4
--- /dev/null
+++ b/tests/wpt/tests/orientation-sensor/resources/sensor-data.js
@@ -0,0 +1,26 @@
+'use strict';
+
+const kAbsoluteOrientationSensorData = {
+ sensorName: 'AbsoluteOrientationSensor',
+ permissionName: 'accelerometer',
+ testDriverName: 'absolute-orientation',
+ featurePolicyNames: ['accelerometer', 'gyroscope', 'magnetometer']
+};
+
+const kRelativeOrientationSensorData = {
+ sensorName: 'RelativeOrientationSensor',
+ permissionName: 'accelerometer',
+ testDriverName: 'relative-orientation',
+ featurePolicyNames: ['accelerometer', 'gyroscope']
+};
+
+const kOrientationReadings = {
+ readings: [{quaternion: [1, 0, 0, 0]}],
+ expectedReadings: [{quaternion: [1, 0, 0, 0]}],
+ expectedRemappedReadings: [{quaternion: [-0.70710678, 0.70710678, 0, 0]}]
+};
+
+const kRotationMatrix = [1, 0, 0, 0,
+ 0, -1, 0, 0,
+ 0, 0, -1, 0,
+ 0, 0, 0, 1];
diff --git a/tests/wpt/tests/pointerevents/pointerevent_after_target_removed.html b/tests/wpt/tests/pointerevents/pointerevent_after_target_removed.html
index 5ab6040cc9c..2dcc94c2b23 100644
--- a/tests/wpt/tests/pointerevents/pointerevent_after_target_removed.html
+++ b/tests/wpt/tests/pointerevents/pointerevent_after_target_removed.html
@@ -106,27 +106,27 @@
// Tests for dispatched pointer events.
addPromiseTest("pointerdown", "pointer", [
"pointerover@child", "pointerenter@parent", "pointerenter@child",
- "pointerdown@child", "(child-removed)", "pointerup@parent",
+ "pointerdown@child", "(child-removed)", "pointerover@parent", "pointerup@parent",
"pointerdown@parent", "pointerup@parent",
"pointerout@parent", "pointerleave@parent"
]);
addPromiseTest("pointerup", "pointer", [
"pointerover@child", "pointerenter@parent", "pointerenter@child",
"pointerdown@child", "pointerup@child", "(child-removed)",
- "pointerdown@parent", "pointerup@parent",
+ "pointerover@parent", "pointerdown@parent", "pointerup@parent",
"pointerout@parent", "pointerleave@parent"
]);
// Same tests for dispatched compatibility mouse events.
addPromiseTest("pointerdown", "mouse", [
"mouseover@child", "mouseenter@parent", "mouseenter@child",
- "(child-removed)", "mousedown@parent", "mouseup@parent",
+ "(child-removed)", "mouseover@parent", "mousedown@parent", "mouseup@parent",
"mousedown@parent", "mouseup@parent",
"mouseout@parent", "mouseleave@parent"
]);
addPromiseTest("pointerup", "mouse", [
"mouseover@child", "mouseenter@parent", "mouseenter@child",
- "mousedown@child", "(child-removed)", "mouseup@parent",
+ "mousedown@child", "(child-removed)", "mouseover@parent", "mouseup@parent",
"mousedown@parent", "mouseup@parent",
"mouseout@parent", "mouseleave@parent"
]);
diff --git a/tests/wpt/tests/requestidlecallback/callback-timeRemaining-cross-realm-method.html b/tests/wpt/tests/requestidlecallback/callback-timeRemaining-cross-realm-method.html
index 383479d64a0..078e2c9379c 100644
--- a/tests/wpt/tests/requestidlecallback/callback-timeRemaining-cross-realm-method.html
+++ b/tests/wpt/tests/requestidlecallback/callback-timeRemaining-cross-realm-method.html
@@ -1,4 +1,4 @@
-<!doctype html><!-- webkit-test-runner [ RequestIdleCallbackEnabled=true ] -->
+<!doctype html>
<meta charset="utf-8">
<meta name="timeout" content="long">
<title>IdleDeadline::timeRemaining() uses relevant global object as a high-res timestamp origin</title>
diff --git a/tests/wpt/tests/service-workers/service-worker/resources/scope1/redirect.py b/tests/wpt/tests/service-workers/service-worker/resources/scope1/redirect.py
index bb4c874aace..025ea671c50 100644
--- a/tests/wpt/tests/service-workers/service-worker/resources/scope1/redirect.py
+++ b/tests/wpt/tests/service-workers/service-worker/resources/scope1/redirect.py
@@ -1,6 +1,8 @@
import os
-import imp
+
+from tools.wpt.utils import load_source
+
# Use the file from the parent directory.
-mod = imp.load_source("_parent", os.path.join(os.path.dirname(os.path.dirname(__file__)),
+mod = load_source("_parent", os.path.join(os.path.dirname(os.path.dirname(__file__)),
os.path.basename(__file__)))
main = mod.main
diff --git a/tests/wpt/tests/service-workers/service-worker/resources/scope2/worker_interception_redirect_webworker.py b/tests/wpt/tests/service-workers/service-worker/resources/scope2/worker_interception_redirect_webworker.py
index bb4c874aace..025ea671c50 100644
--- a/tests/wpt/tests/service-workers/service-worker/resources/scope2/worker_interception_redirect_webworker.py
+++ b/tests/wpt/tests/service-workers/service-worker/resources/scope2/worker_interception_redirect_webworker.py
@@ -1,6 +1,8 @@
import os
-import imp
+
+from tools.wpt.utils import load_source
+
# Use the file from the parent directory.
-mod = imp.load_source("_parent", os.path.join(os.path.dirname(os.path.dirname(__file__)),
+mod = load_source("_parent", os.path.join(os.path.dirname(os.path.dirname(__file__)),
os.path.basename(__file__)))
main = mod.main
diff --git a/tests/wpt/tests/service-workers/service-worker/resources/subdir/worker_interception_redirect_webworker.py b/tests/wpt/tests/service-workers/service-worker/resources/subdir/worker_interception_redirect_webworker.py
index bb4c874aace..025ea671c50 100644
--- a/tests/wpt/tests/service-workers/service-worker/resources/subdir/worker_interception_redirect_webworker.py
+++ b/tests/wpt/tests/service-workers/service-worker/resources/subdir/worker_interception_redirect_webworker.py
@@ -1,6 +1,8 @@
import os
-import imp
+
+from tools.wpt.utils import load_source
+
# Use the file from the parent directory.
-mod = imp.load_source("_parent", os.path.join(os.path.dirname(os.path.dirname(__file__)),
+mod = load_source("_parent", os.path.join(os.path.dirname(os.path.dirname(__file__)),
os.path.basename(__file__)))
main = mod.main
diff --git a/tests/wpt/tests/storage-access-api/helpers.js b/tests/wpt/tests/storage-access-api/helpers.js
index 7d259b21676..24ed21a976b 100644
--- a/tests/wpt/tests/storage-access-api/helpers.js
+++ b/tests/wpt/tests/storage-access-api/helpers.js
@@ -278,3 +278,15 @@ async function MaybeSetStorageAccess(origin, embedding_origin, value) {
// in the test.
}
}
+
+// Starts a dedicated worker in the given frame.
+function StartDedicatedWorker(frame) {
+ return PostMessageAndAwaitReply(
+ { command: "start_dedicated_worker" }, frame.contentWindow);
+}
+
+// Sends a message to the dedicated worker in the given frame.
+function MessageWorker(frame, message = {}) {
+ return PostMessageAndAwaitReply(
+ { command: "message_worker", message }, frame.contentWindow);
+}
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
new file mode 100644
index 00000000000..86caf819182
--- /dev/null
+++ b/tests/wpt/tests/storage-access-api/requestStorageAccess-dedicated-worker.tentative.sub.https.window.js
@@ -0,0 +1,67 @@
+// META: script=helpers.js
+// META: script=/cookies/resources/cookie-helper.sub.js
+// META: script=/resources/testdriver.js
+// META: script=/resources/testdriver-vendor.js
+'use strict';
+
+(function() {
+ const altRoot = "https://{{hosts[alt][]}}:{{ports[https][0]}}";
+
+ const responderPath = "/storage-access-api/resources/script-with-cookie-header.py?script=embedded_responder.js";
+ const echoCookiesPath = `/storage-access-api/resources/echo-cookie-header.py`;
+
+ const altRootResponder = `${altRoot}${responderPath}`;
+ const altRootEchoCookies = `${altRoot}${echoCookiesPath}`;
+
+ async function SetUpResponderFrame(t, url) {
+ const frame = await CreateFrame(url);
+
+ await SetPermissionInFrame(frame, [{ name: 'storage-access' }, 'granted']);
+ t.add_cleanup(async () => {
+ await test_driver.delete_all_cookies();
+ await SetPermissionInFrame(frame, [{ name: 'storage-access' }, 'prompt']);
+ await MaybeSetStorageAccess("*", "*", "allowed");
+ });
+
+ return frame;
+ }
+
+ promise_test(async (t) => {
+ await MaybeSetStorageAccess("*", "*", "blocked");
+ await SetFirstPartyCookieAndUnsetStorageAccessPermission(altRoot);
+
+ const frame = await SetUpResponderFrame(t, altRootResponder);
+ assert_true(await RequestStorageAccessInFrame(frame), "requestStorageAccess resolves without requiring a gesture.");
+ assert_true(await FrameHasStorageAccess(frame), "frame has storage access after request.");
+ assert_true(await HasUnpartitionedCookie(frame), "frame has access to cookies after request.");
+
+ await StartDedicatedWorker(frame);
+
+ assert_equals(
+ await MessageWorker(frame, {command: "fetch", url: altRootEchoCookies}),
+ "cookie=unpartitioned", "Worker's fetch is credentialed.");
+ }, "Workers inherit storage access");
+
+ promise_test(async (t) => {
+ await MaybeSetStorageAccess("*", "*", "blocked");
+ await SetFirstPartyCookieAndUnsetStorageAccessPermission(altRoot);
+
+ const frame = await SetUpResponderFrame(t, altRootResponder);
+
+ await StartDedicatedWorker(frame);
+ assert_equals(
+ await MessageWorker(frame, {command: "fetch", url: altRootEchoCookies}),
+ "", "Worker's first fetch is uncredentialed.");
+
+ // Since the parent document obtains storage access *after* having created
+ // the worker, this should have no effect on the worker.
+ assert_true(await RequestStorageAccessInFrame(frame), "requestStorageAccess resolves without requiring a gesture.");
+ assert_true(await FrameHasStorageAccess(frame), "frame has storage access after request.");
+ assert_true(await HasUnpartitionedCookie(frame), "frame has access to cookies after request.");
+
+ assert_equals(
+ await MessageWorker(frame, {command: "fetch", url: altRootEchoCookies}),
+ "", "Worker's second fetch is uncredentialed.");
+ }, "Workers don't observe parent's storage access");
+
+}());
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 634079289b0..e9cc39bc71a 100644
--- a/tests/wpt/tests/storage-access-api/resources/embedded_responder.js
+++ b/tests/wpt/tests/storage-access-api/resources/embedded_responder.js
@@ -4,6 +4,18 @@
test_driver.set_test_context(window.top);
+let worker;
+
+function waitForWorkerMessage(worker) {
+ return new Promise(resolve => {
+ const listener = (event) => {
+ worker.removeEventListener("message", listener);
+ resolve(event.data);
+ };
+ worker.addEventListener("message", listener);
+ });
+}
+
window.addEventListener("message", async (event) => {
function reply(data) {
event.source.postMessage(
@@ -51,6 +63,16 @@ window.addEventListener("message", async (event) => {
case "cors fetch":
reply(await fetch(event.data.url, {mode: 'cors', credentials: 'include'}).then((resp) => resp.text()));
break;
+ case "start_dedicated_worker":
+ worker = new Worker("embedded_worker.js");
+ reply(undefined);
+ break;
+ case "message_worker": {
+ const p = waitForWorkerMessage(worker);
+ worker.postMessage(event.data.message);
+ reply(await p.then(resp => resp.data))
+ break;
+ }
default:
}
});
diff --git a/tests/wpt/tests/storage-access-api/resources/embedded_worker.js b/tests/wpt/tests/storage-access-api/resources/embedded_worker.js
new file mode 100644
index 00000000000..f3a0fb257ad
--- /dev/null
+++ b/tests/wpt/tests/storage-access-api/resources/embedded_worker.js
@@ -0,0 +1,17 @@
+"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/storage-access-beyond-cookies-iframe-iframe.html b/tests/wpt/tests/storage-access-api/resources/storage-access-beyond-cookies-iframe-iframe.html
new file mode 100644
index 00000000000..348efc5dec4
--- /dev/null
+++ b/tests/wpt/tests/storage-access-api/resources/storage-access-beyond-cookies-iframe-iframe.html
@@ -0,0 +1,75 @@
+<!doctype html>
+<meta charset="utf-8">
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script>
+(async function() {
+ 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");
+ let message = "HasAccess for " + type;
+ // Step 6 (storage-access-api/storage-access-beyond-cookies.{}.tentative.sub.https.html)
+ try {
+ await test_driver.set_permission({ name: 'storage-access' }, 'granted');
+ switch (type) {
+ case "sessionStorage": {
+ const handle = await document.requestStorageAccess({sessionStorage: true});
+ if (id != handle.sessionStorage.getItem("test")) {
+ message = "No first-party Session Storage access";
+ }
+ if (!!window.sessionStorage.getItem("test")) {
+ message = "Handle should not override window Session Storage";
+ }
+ handle.sessionStorage.clear();
+ break;
+ }
+ case "localStorage": {
+ const handle = await document.requestStorageAccess({localStorage: true});
+ if (id != handle.localStorage.getItem("test")) {
+ message = "No first-party Local Storage access";
+ }
+ if (!!window.localStorage.getItem("test")) {
+ message = "Handle should not override window Local Storage";
+ }
+ handle.localStorage.clear();
+ break;
+ }
+ case "indexedDB": {
+ const handle = await document.requestStorageAccess({indexedDB: true});
+ const handle_dbs = await handle.indexedDB.databases();
+ if (handle_dbs.length != 1 || handle_dbs[0].name != id) {
+ message = "No first-party IndexedDB access";
+ }
+ const local_dbs = await window.indexedDB.databases();
+ if (local_dbs.length != 0) {
+ message = "Handle should not override window IndexedDB";
+ }
+ await handle.indexedDB.deleteDatabase(id);
+ break;
+ }
+ case "locks": {
+ const handle = await document.requestStorageAccess({locks: true});
+ const handle_state = await handle.locks.query();
+ if (handle_state.held.length != 1 || handle_state.held[0].name != id) {
+ message = "No first-party Web Lock access";
+ }
+ const local_state = await window.navigator.locks.query();
+ if (local_state.held.length != 0) {
+ message = "Handle should not override window Web Locks";
+ }
+ await handle.locks.request(id, {steal: true}, async () => {});
+ break;
+ }
+ default: {
+ message = "Unexpected type " + type;
+ break;
+ }
+ }
+ } catch (_) {
+ message = "Unable to load handle in same-origin context for " + type;
+ }
+ // Step 7 (storage-access-api/storage-access-beyond-cookies.{}.tentative.sub.https.html)
+ await test_driver.set_permission({ name: 'storage-access' }, 'prompt');
+ window.top.postMessage(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
new file mode 100644
index 00000000000..fae51c2d547
--- /dev/null
+++ b/tests/wpt/tests/storage-access-api/resources/storage-access-beyond-cookies-iframe.sub.html
@@ -0,0 +1,62 @@
+<!doctype html>
+<meta charset="utf-8">
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<body>
+<script>
+(async function() {
+ 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");
+ let message = "";
+ // Step 4 (storage-access-api/storage-access-beyond-cookies.{}.tentative.sub.https.html)
+ try {
+ await test_driver.set_permission({ name: 'storage-access' }, 'granted');
+ const handle = await document.requestStorageAccess({all: true});
+ switch (type) {
+ case "sessionStorage": {
+ if (!!handle.sessionStorage.getItem("test")) {
+ message = "Cross-site first-party Session Storage should be empty";
+ }
+ break;
+ }
+ case "localStorage": {
+ if (!!handle.localStorage.getItem("test")) {
+ message = "Cross-site first-party Local Storage should be empty";
+ }
+ break;
+ }
+ case "indexedDB": {
+ const dbs = await handle.indexedDB.databases();
+ if (dbs.length != 0) {
+ message = "Cross-site first-party IndexedDB should be empty";
+ }
+ break;
+ }
+ case "locks": {
+ const state = await handle.locks.query();
+ if (state.held.length != 0) {
+ message = "Cross-site first-party Web Locks should be empty";
+ }
+ break;
+ }
+ default: {
+ message = "Unexpected type " + type;
+ break;
+ }
+ }
+ } catch (_) {
+ message = "Unable to load handle in cross-site context for all";
+ }
+ await test_driver.set_permission({ name: 'storage-access' }, 'prompt');
+ if (message) {
+ window.top.postMessage(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);
+})();
+</script>
+</body>
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
new file mode 100644
index 00000000000..18c4317bbe9
--- /dev/null
+++ b/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.indexedDB.tentative.sub.https.window.js
@@ -0,0 +1,33 @@
+// 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 listener for "HasAccess" message.
+// Step 2 (top-frame) Add data to first-party indexed db.
+// Step 3 (top-frame) Embed an iframe that's cross-site with top-frame.
+// Step 4 (sub-frame) Try to use storage access API and read first-party data.
+// 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 and read first-party data.
+// Step 7 (sub-sub-frame) Send "HasAccess for indexedDB" message to top-frame.
+// Step 8 (top-frame) Receive "HasAccess for indexedDB" message and cleanup.
+
+async_test(t => {
+ // Step 1
+ window.addEventListener("message", t.step_func(e => {
+ // Step 8
+ assert_equals(e.data, "HasAccess for indexedDB", "Storage Access API should be accessible and return first-party data");
+ t.done();
+ }));
+
+ // Step 2
+ const id = Date.now();
+ let request = window.indexedDB.open(id);
+ request.onsuccess = () => {
+ // Step 3
+ 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=indexedDB&id="+id;
+ document.body.appendChild(iframe);
+ };
+}, "Verify StorageAccessAPIBeyondCookies for IndexedDB");
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
new file mode 100644
index 00000000000..108e778766d
--- /dev/null
+++ b/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.localStorage.tentative.sub.https.window.js
@@ -0,0 +1,32 @@
+// 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 listener for "HasAccess" message.
+// Step 2 (top-frame) Add data to first-party local storage.
+// Step 3 (top-frame) Embed an iframe that's cross-site with top-frame.
+// Step 4 (sub-frame) Try to use storage access API and read first-party data.
+// 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 and read first-party data.
+// Step 7 (sub-sub-frame) Send "HasAccess for localStorage" message to top-frame.
+// Step 8 (top-frame) Receive "HasAccess for localStorage" message and cleanup.
+
+async_test(t => {
+ // Step 1
+ window.addEventListener("message", t.step_func(e => {
+ // Step 8
+ assert_equals(e.data, "HasAccess for localStorage", "Storage Access API should be accessible and return first-party data");
+ t.done();
+ }));
+
+ // Step 2
+ const id = Date.now();
+ window.localStorage.setItem("test", id);
+
+ // Step 3
+ 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=localStorage&id="+id;
+ document.body.appendChild(iframe);
+}, "Verify StorageAccessAPIBeyondCookies for Local Storage");
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
new file mode 100644
index 00000000000..83aa28c018e
--- /dev/null
+++ b/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.locks.tentative.sub.https.window.js
@@ -0,0 +1,34 @@
+// 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 listener for "HasAccess" message.
+// Step 2 (top-frame) Secure first-party web lock.
+// Step 3 (top-frame) Embed an iframe that's cross-site with top-frame.
+// Step 4 (sub-frame) Try to use storage access API and read first-party data.
+// 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 and read first-party data.
+// Step 7 (sub-sub-frame) Send "HasAccess for locks" message to top-frame.
+// Step 8 (top-frame) Receive "HasAccess for locks" message and cleanup.
+
+async_test(t => {
+ // Step 1
+ window.addEventListener("message", t.step_func(e => {
+ // Step 8
+ assert_equals(e.data, "HasAccess for locks", "Storage Access API should be accessible and return first-party data");
+ t.done();
+ }));
+
+ // Step 2
+ const id = Date.now();
+ window.navigator.locks.request(id, async () => {
+ // Step 3
+ 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=locks&id="+id;
+ document.body.appendChild(iframe);
+ // We need to sleep so this locks stays engaged until the test succeeds or times out.
+ await new Promise(r => setTimeout(r, 30000))
+ }).catch (() => {/*We expect this lock to be stolen if the test runs correctly.*/});
+}, "Verify StorageAccessAPIBeyondCookies for Web Locks");
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
new file mode 100644
index 00000000000..2e504851c22
--- /dev/null
+++ b/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.sessionStorage.tentative.sub.https.window.js
@@ -0,0 +1,32 @@
+// 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 listener for "HasAccess" message.
+// Step 2 (top-frame) Add data to first-party session storage.
+// Step 3 (top-frame) Embed an iframe that's cross-site with top-frame.
+// Step 4 (sub-frame) Try to use storage access API and read first-party data.
+// 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 and read first-party data.
+// Step 7 (sub-sub-frame) Send "HasAccess for sessionStorage" message to top-frame.
+// Step 8 (top-frame) Receive "HasAccess for sessionStorage" message and cleanup.
+
+async_test(t => {
+ // Step 1
+ window.addEventListener("message", t.step_func(e => {
+ // Step 8
+ assert_equals(e.data, "HasAccess for sessionStorage", "Storage Access API should be accessible and return first-party data");
+ t.done();
+ }));
+
+ // Step 2
+ const id = Date.now();
+ window.sessionStorage.setItem("test", id);
+
+ // Step 3
+ 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=sessionStorage&id=" + id;
+ document.body.appendChild(iframe);
+}, "Verify StorageAccessAPIBeyondCookies for Session Storage");
diff --git a/tests/wpt/tests/storage/estimate-indexeddb.https.any.js b/tests/wpt/tests/storage/estimate-indexeddb.https.any.js
index f0b82b9fa09..6577b021ad5 100644
--- a/tests/wpt/tests/storage/estimate-indexeddb.https.any.js
+++ b/tests/wpt/tests/storage/estimate-indexeddb.https.any.js
@@ -1,21 +1,8 @@
// META: title=StorageManager: estimate() for indexeddb
// META: script=/storage/buckets/resources/util.js
-test(t => {
- assert_true('estimate' in navigator.storage);
- assert_equals(typeof navigator.storage.estimate, 'function');
- assert_true(navigator.storage.estimate() instanceof Promise);
-}, 'estimate() method exists and returns a Promise');
-
-promise_test(async t => {
- const estimate = await navigator.storage.estimate();
- assert_equals(typeof estimate, 'object');
- assert_true('usage' in estimate);
- assert_equals(typeof estimate.usage, 'number');
- assert_true('quota' in estimate);
- assert_equals(typeof estimate.quota, 'number');
-}, 'estimate() resolves to dictionary with members');
-
+// Technically, this verifies unspecced behavior. See
+// https://github.com/whatwg/storage/issues/110 for defining this behavior.
promise_test(async t => {
const arraySize = 1e6;
const objectStoreName = "storageManager";
diff --git a/tests/wpt/tests/storage/storagemanager-estimate.https.any.js b/tests/wpt/tests/storage/storagemanager-estimate.https.any.js
index c2f5c569dc5..3b6f4d8edc4 100644
--- a/tests/wpt/tests/storage/storagemanager-estimate.https.any.js
+++ b/tests/wpt/tests/storage/storagemanager-estimate.https.any.js
@@ -1,60 +1,16 @@
// META: title=StorageManager: estimate()
-test(function(t) {
- assert_true(navigator.storage.estimate() instanceof Promise);
-}, 'estimate() method returns a Promise');
+test(t => {
+ assert_true('estimate' in navigator.storage);
+ assert_equals(typeof navigator.storage.estimate, 'function');
+ assert_true(navigator.storage.estimate() instanceof Promise);
+}, 'estimate() method exists and returns a Promise');
-promise_test(function(t) {
- return navigator.storage.estimate().then(function(result) {
- assert_equals(typeof result, 'object');
- assert_true('usage' in result);
- assert_equals(typeof result.usage, 'number');
- assert_true('quota' in result);
- assert_equals(typeof result.quota, 'number');
- });
+promise_test(async t => {
+ const result = await navigator.storage.estimate();
+ assert_equals(typeof result, 'object');
+ assert_true('usage' in result);
+ assert_equals(typeof result.usage, 'number');
+ assert_true('quota' in result);
+ assert_equals(typeof result.quota, 'number');
}, 'estimate() resolves to dictionary with members');
-
-promise_test(function(t) {
- const large_value = new Uint8Array(1e6);
- const dbname = `db-${location}-${t.name}`;
- let db, before, after;
-
- indexedDB.deleteDatabase(dbname);
- return new Promise((resolve, reject) => {
- const open = indexedDB.open(dbname);
- open.onerror = () => { reject(open.error); };
- open.onupgradeneeded = () => {
- const connection = open.result;
- connection.createObjectStore('store');
- };
- open.onsuccess = () => {
- const connection = open.result;
- t.add_cleanup(() => {
- connection.close();
- indexedDB.deleteDatabase(dbname);
- });
- resolve(connection);
- };
- })
- .then(connection => {
- db = connection;
- return navigator.storage.estimate();
- })
- .then(estimate => {
- before = estimate.usage;
- return new Promise((resolve, reject) => {
- const tx = db.transaction('store', 'readwrite');
- tx.objectStore('store').put(large_value, 'key');
- tx.onabort = () => { reject(tx.error); };
- tx.oncomplete = () => { resolve(); };
- });
- })
- .then(() => {
- return navigator.storage.estimate();
- })
- .then(estimate => {
- after = estimate.usage;
- assert_greater_than(after, before,
- 'estimated usage should increase');
- });
-}, 'estimate() shows usage increase after 1MB IndexedDB record is stored');
diff --git a/tests/wpt/tests/svg/extensibility/foreignObject/masked.html b/tests/wpt/tests/svg/extensibility/foreignObject/masked.html
index 1c7a332d7f9..a4ca2fd8521 100644
--- a/tests/wpt/tests/svg/extensibility/foreignObject/masked.html
+++ b/tests/wpt/tests/svg/extensibility/foreignObject/masked.html
@@ -3,7 +3,7 @@
<link rel="match" href="masked-ref.html">
<link rel="author" title="Chris Harrelson" href="mailto:chrishtr@chromium.org">
<link rel="help" href="https://svgwg.org/svg2-draft/single-page.html#embedded-ForeignObjectElement"/>
-<meta name="fuzzy" content="maxDifference=0-37; totalPixels=0-124">
+<meta name="fuzzy" content="maxDifference=0-138; totalPixels=0-124">
<svg style="display: block">
<foreignObject x="0" y="0" width="32" height="32" mask="url(#circle)">
<div style="width: 32px; height: 32px; background: green"></div>
diff --git a/tests/wpt/tests/svg/pservers/scripted/pattern-transform-clear.svg b/tests/wpt/tests/svg/pservers/scripted/pattern-transform-clear.svg
new file mode 100644
index 00000000000..6800fd8d20d
--- /dev/null
+++ b/tests/wpt/tests/svg/pservers/scripted/pattern-transform-clear.svg
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:h="http://www.w3.org/1999/xhtml">
+ <title>SVG Paint Servers: Clear should cause patternTransform to be ignored.</title>
+ <metadata>
+ <h:link rel="help" href="https://svgwg.org/svg2-draft/pservers.html#PatternElementPatternTransformAttribute"/>
+ <h:link rel="match" href="../reftests/reference/green-100x100.svg"/>
+ </metadata>
+ <pattern id="p1" patternTransform="scale(2)"/>
+ <pattern id="p" href="#p1" viewBox="0 0 50 50" patternTransform="scale(1)" width="100%" height="100%">
+ <rect fill="red" width="50" height="50"/>
+ <rect fill="green" width="25" height="25"/>
+ </pattern>
+ <rect fill="url(#p)" width="100" height="100"/>
+ <script><![CDATA[
+ document.getElementById("p").patternTransform.baseVal.clear();
+ ]]></script>
+</svg>
diff --git a/tests/wpt/tests/tools/ci/ci_wptrunner_infrastructure.sh b/tests/wpt/tests/tools/ci/ci_wptrunner_infrastructure.sh
index ebe7870afa8..fc6907f8de6 100755
--- a/tests/wpt/tests/tools/ci/ci_wptrunner_infrastructure.sh
+++ b/tests/wpt/tests/tools/ci/ci_wptrunner_infrastructure.sh
@@ -1,19 +1,19 @@
#!/bin/bash
set -ex
-SCRIPT_DIR=$(cd $(dirname "$0") && pwd -P)
+REL_DIR_NAME=$(dirname "$0")
+SCRIPT_DIR=$(cd "$REL_DIR_NAME" && pwd -P)
WPT_ROOT=$SCRIPT_DIR/../..
-cd $WPT_ROOT
+cd "$WPT_ROOT"
run_infra_test() {
- TERM=dumb ./wpt run --log-mach - --yes --manifest ~/meta/MANIFEST.json --metadata infrastructure/metadata/ --install-fonts --install-webdriver --log-wptreport="/home/test/artifacts/wptreport-$1.json" $2 $1 infrastructure/
+ ./tools/ci/taskcluster-run.py "$1" "$2" -- --metadata=infrastructure/metadata/ --log-wptreport="../artifacts/wptreport-$1.json" --include=infrastructure/
}
main() {
- ./wpt manifest --rebuild -p ~/meta/MANIFEST.json
- run_infra_test "chrome" "--binary=$(which google-chrome-unstable) --enable-swiftshader --channel dev $1"
- run_infra_test "firefox" "--binary=~/build/firefox/firefox $1"
- run_infra_test "firefox_android" "--install-browser --logcat-dir=/home/test/artifacts/ $1"
+ run_infra_test "chrome" "dev"
+ run_infra_test "firefox" "nightly"
+ run_infra_test "firefox_android" "nightly"
}
-main $1
+main
diff --git a/tests/wpt/tests/tools/ci/taskcluster-run.py b/tests/wpt/tests/tools/ci/taskcluster-run.py
index c801f61e8e8..2917d8f3402 100755
--- a/tests/wpt/tests/tools/ci/taskcluster-run.py
+++ b/tests/wpt/tests/tools/ci/taskcluster-run.py
@@ -10,13 +10,15 @@ import subprocess
import sys
-def get_browser_args(product, channel):
+def get_browser_args(product, channel, artifact_path):
if product == "firefox":
local_binary = os.path.expanduser(os.path.join("~", "build", "firefox", "firefox"))
if os.path.exists(local_binary):
return ["--binary=%s" % local_binary]
print("WARNING: Local firefox binary not found")
return ["--install-browser", "--install-webdriver"]
+ if product == "firefox_android":
+ return ["--install-browser", "--install-webdriver", "--logcat-dir", artifact_path]
if product == "servo":
return ["--install-browser", "--processes=12"]
if product == "chrome" or product == "chromium":
@@ -52,7 +54,7 @@ def gzip_file(filename, delete_original=True):
os.unlink(filename)
-def main(product, channel, commit_range, wpt_args):
+def main(product, channel, commit_range, artifact_path, wpt_args):
"""Invoke the `wpt run` command according to the needs of the Taskcluster
continuous integration service."""
@@ -84,16 +86,18 @@ def main(product, channel, commit_range, wpt_args):
"--no-headless",
"--verify-log-full"
]
- wpt_args += get_browser_args(product, channel)
+ wpt_args += get_browser_args(product, channel, artifact_path)
# Hack to run servo with one process only for wdspec
if product == "servo" and "--test-type=wdspec" in wpt_args:
wpt_args = [item for item in wpt_args if not item.startswith("--processes")]
- command = ["python3", "./wpt", "run"] + wpt_args + [product]
+ wpt_args.append(product)
+
+ command = ["python3", "./wpt", "run"] + wpt_args
logger.info("Executing command: %s" % " ".join(command))
- with open("/home/test/artifacts/checkrun.md", "a") as f:
+ with open(os.path.join(artifact_path, "checkrun.md"), "a") as f:
f.write("\n**WPT Command:** `%s`\n\n" % " ".join(command))
retcode = subprocess.call(command, env=dict(os.environ, TERM="dumb"))
@@ -114,6 +118,9 @@ if __name__ == "__main__":
help="""Git commit range. If specified, this will be
supplied to the `wpt tests-affected` command to
determine the list of test to execute""")
+ parser.add_argument("--artifact-path", action="store",
+ default="/home/test/artifacts/",
+ help="Path to store output files")
parser.add_argument("product", action="store",
help="Browser to run tests in")
parser.add_argument("channel", action="store",
diff --git a/tests/wpt/tests/tools/ci/tc/tasks/test.yml b/tests/wpt/tests/tools/ci/tc/tasks/test.yml
index 598a3395def..7c1a4df994c 100644
--- a/tests/wpt/tests/tools/ci/tc/tasks/test.yml
+++ b/tests/wpt/tests/tools/ci/tc/tasks/test.yml
@@ -296,12 +296,6 @@ tasks:
use:
- trigger-daily
- trigger-push
- - vars:
- browser: firefox_android
- channel: nightly
- use:
- - trigger-daily
- - trigger-push
do:
- ${vars.browser}-${vars.channel}-${vars.suite}:
use:
diff --git a/tests/wpt/tests/tools/ci/tc/tests/test_valid.py b/tests/wpt/tests/tools/ci/tc/tests/test_valid.py
index 1d50115f91d..36c2d0a986c 100644
--- a/tests/wpt/tests/tools/ci/tc/tests/test_valid.py
+++ b/tests/wpt/tests/tools/ci/tc/tests/test_valid.py
@@ -325,8 +325,7 @@ def test_verify_payload():
'wpt-firefox_android-nightly-crashtest-1',
'wpt-firefox-stable-print-reftest-1',
'wpt-chromium-nightly-print-reftest-1',
- 'wpt-chrome-stable-print-reftest-1',
- 'wpt-firefox_android-nightly-print-reftest-1'])
+ 'wpt-chrome-stable-print-reftest-1'])
])
def test_schedule_tasks(event_path, is_pr, files_changed, expected):
with mock.patch("tools.ci.tc.decision.get_fetch_rev", return_value=(None, None, None)):
diff --git a/tests/wpt/tests/tools/runner/update_manifest.py b/tests/wpt/tests/tools/runner/update_manifest.py
index a7f72b35b33..58b9ac4d84b 100644
--- a/tests/wpt/tests/tools/runner/update_manifest.py
+++ b/tests/wpt/tests/tools/runner/update_manifest.py
@@ -1,16 +1,18 @@
# mypy: ignore-errors
-import imp
import json
import os
+from tools.wpt.utils import load_source
+
here = os.path.dirname(__file__)
-localpaths = imp.load_source("localpaths", os.path.abspath(os.path.join(here, os.pardir, "localpaths.py")))
+localpaths = load_source("localpaths", os.path.abspath(os.path.join(here, os.pardir, "localpaths.py")))
root = localpaths.repo_root
from manifest import manifest
+
def main(request, response):
path = os.path.join(root, "MANIFEST.json")
diff --git a/tests/wpt/tests/tools/webdriver/webdriver/__init__.py b/tests/wpt/tests/tools/webdriver/webdriver/__init__.py
index a81751407e7..dfd264f8b29 100644
--- a/tests/wpt/tests/tools/webdriver/webdriver/__init__.py
+++ b/tests/wpt/tests/tools/webdriver/webdriver/__init__.py
@@ -2,13 +2,14 @@
from .client import (
Cookies,
- Element,
Find,
- Frame,
Session,
ShadowRoot,
Timeouts,
- Window)
+ WebElement,
+ WebFrame,
+ WebWindow,
+)
from .error import (
ElementNotSelectableException,
ElementNotVisibleException,
diff --git a/tests/wpt/tests/tools/webdriver/webdriver/client.py b/tests/wpt/tests/tools/webdriver/webdriver/client.py
index f33fc34dac9..e41df7f5764 100644
--- a/tests/wpt/tests/tools/webdriver/webdriver/client.py
+++ b/tests/wpt/tests/tools/webdriver/webdriver/client.py
@@ -295,9 +295,7 @@ class Actions:
return ActionSequence(self.session, *args, **kwargs)
-class Window:
- identifier = "window-fcc6-11e5-b4f8-330a88ab9d7f"
-
+class BrowserWindow:
def __init__(self, session):
self.session = session
@@ -372,59 +370,6 @@ class Window:
def fullscreen(self):
return self.session.send_session_command("POST", "window/fullscreen")
- @classmethod
- def from_json(cls, json, session):
- uuid = json[Window.identifier]
- return cls(uuid, session)
-
-
-class Frame:
- identifier = "frame-075b-4da1-b6ba-e579c2d3230a"
-
- def __init__(self, session):
- self.session = session
-
- @classmethod
- def from_json(cls, json, session):
- uuid = json[Frame.identifier]
- return cls(uuid, session)
-
-
-class ShadowRoot:
- identifier = "shadow-6066-11e4-a52e-4f735466cecf"
-
- def __init__(self, session, id):
- """
- Construct a new shadow root representation.
-
- :param id: Shadow root UUID which must be unique across
- all browsing contexts.
- :param session: Current ``webdriver.Session``.
- """
- self.id = id
- self.session = session
-
- @classmethod
- def from_json(cls, json, session):
- uuid = json[ShadowRoot.identifier]
- return cls(session, uuid)
-
- def send_shadow_command(self, method, uri, body=None):
- url = f"shadow/{self.id}/{uri}"
- return self.session.send_session_command(method, url, body)
-
- @command
- def find_element(self, strategy, selector):
- body = {"using": strategy,
- "value": selector}
- return self.send_shadow_command("POST", "element", body)
-
- @command
- def find_elements(self, strategy, selector):
- body = {"using": strategy,
- "value": selector}
- return self.send_shadow_command("POST", "elements", body)
-
class Find:
def __init__(self, session):
@@ -512,7 +457,7 @@ class Session:
self.extension_cls = extension
self.timeouts = Timeouts(self)
- self.window = Window(self)
+ self.window = BrowserWindow(self)
self.find = Find(self)
self.alert = UserPrompt(self)
self.actions = Actions(self)
@@ -795,7 +740,44 @@ class Session:
def screenshot(self):
return self.send_session_command("GET", "screenshot")
-class Element:
+
+class ShadowRoot:
+ identifier = "shadow-6066-11e4-a52e-4f735466cecf"
+
+ def __init__(self, session, id):
+ """
+ Construct a new shadow root representation.
+
+ :param id: Shadow root UUID which must be unique across
+ all browsing contexts.
+ :param session: Current ``webdriver.Session``.
+ """
+ self.id = id
+ self.session = session
+
+ @classmethod
+ def from_json(cls, json, session):
+ uuid = json[ShadowRoot.identifier]
+ return cls(session, uuid)
+
+ def send_shadow_command(self, method, uri, body=None):
+ url = f"shadow/{self.id}/{uri}"
+ return self.session.send_session_command(method, url, body)
+
+ @command
+ def find_element(self, strategy, selector):
+ body = {"using": strategy,
+ "value": selector}
+ return self.send_shadow_command("POST", "element", body)
+
+ @command
+ def find_elements(self, strategy, selector):
+ body = {"using": strategy,
+ "value": selector}
+ return self.send_shadow_command("POST", "elements", body)
+
+
+class WebElement:
"""
Representation of a web element.
@@ -818,12 +800,12 @@ class Element:
return "<%s %s>" % (self.__class__.__name__, self.id)
def __eq__(self, other):
- return (isinstance(other, Element) and self.id == other.id and
+ return (isinstance(other, WebElement) and self.id == other.id and
self.session == other.session)
@classmethod
def from_json(cls, json, session):
- uuid = json[Element.identifier]
+ uuid = json[WebElement.identifier]
return cls(session, uuid)
def send_element_command(self, method, uri, body=None):
@@ -902,3 +884,42 @@ class Element:
@command
def property(self, name):
return self.send_element_command("GET", "property/%s" % name)
+
+class WebFrame:
+ identifier = "frame-075b-4da1-b6ba-e579c2d3230a"
+
+ def __init__(self, session, id):
+ self.id = id
+ self.session = session
+
+ def __repr__(self):
+ return "<%s %s>" % (self.__class__.__name__, self.id)
+
+ def __eq__(self, other):
+ return (isinstance(other, WebFrame) and self.id == other.id and
+ self.session == other.session)
+
+ @classmethod
+ def from_json(cls, json, session):
+ uuid = json[WebFrame.identifier]
+ return cls(session, uuid)
+
+
+class WebWindow:
+ identifier = "window-fcc6-11e5-b4f8-330a88ab9d7f"
+
+ def __init__(self, session, id):
+ self.id = id
+ self.session = session
+
+ def __repr__(self):
+ return "<%s %s>" % (self.__class__.__name__, self.id)
+
+ def __eq__(self, other):
+ return (isinstance(other, WebWindow) and self.id == other.id and
+ self.session == other.session)
+
+ @classmethod
+ def from_json(cls, json, session):
+ uuid = json[WebWindow.identifier]
+ return cls(session, uuid)
diff --git a/tests/wpt/tests/tools/webdriver/webdriver/protocol.py b/tests/wpt/tests/tools/webdriver/webdriver/protocol.py
index 1972c3fce21..d6c89af22be 100644
--- a/tests/wpt/tests/tools/webdriver/webdriver/protocol.py
+++ b/tests/wpt/tests/tools/webdriver/webdriver/protocol.py
@@ -16,14 +16,14 @@ class Encoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, (list, tuple)):
return [self.default(x) for x in obj]
- elif isinstance(obj, webdriver.Element):
- return {webdriver.Element.identifier: obj.id}
- elif isinstance(obj, webdriver.Frame):
- return {webdriver.Frame.identifier: obj.id}
- elif isinstance(obj, webdriver.Window):
- return {webdriver.Frame.identifier: obj.id}
+ elif isinstance(obj, webdriver.WebElement):
+ return {webdriver.WebElement.identifier: obj.id}
+ elif isinstance(obj, webdriver.WebFrame):
+ return {webdriver.WebFrame.identifier: obj.id}
elif isinstance(obj, webdriver.ShadowRoot):
return {webdriver.ShadowRoot.identifier: obj.id}
+ elif isinstance(obj, webdriver.WebWindow):
+ return {webdriver.WebWindow.identifier: obj.id}
return super().default(obj)
@@ -36,14 +36,14 @@ class Decoder(json.JSONDecoder):
def object_hook(self, payload):
if isinstance(payload, (list, tuple)):
return [self.object_hook(x) for x in payload]
- elif isinstance(payload, dict) and webdriver.Element.identifier in payload:
- return webdriver.Element.from_json(payload, self.session)
- elif isinstance(payload, dict) and webdriver.Frame.identifier in payload:
- return webdriver.Frame.from_json(payload, self.session)
- elif isinstance(payload, dict) and webdriver.Window.identifier in payload:
- return webdriver.Window.from_json(payload, self.session)
+ elif isinstance(payload, dict) and webdriver.WebElement.identifier in payload:
+ return webdriver.WebElement.from_json(payload, self.session)
+ elif isinstance(payload, dict) and webdriver.WebFrame.identifier in payload:
+ return webdriver.WebFrame.from_json(payload, self.session)
elif isinstance(payload, dict) and webdriver.ShadowRoot.identifier in payload:
return webdriver.ShadowRoot.from_json(payload, self.session)
+ elif isinstance(payload, dict) and webdriver.WebWindow.identifier in payload:
+ return webdriver.WebWindow.from_json(payload, self.session)
elif isinstance(payload, dict):
return {k: self.object_hook(v) for k, v in payload.items()}
return payload
diff --git a/tests/wpt/tests/tools/webdriver/webdriver/transport.py b/tests/wpt/tests/tools/webdriver/webdriver/transport.py
index e1e16bdebad..ca1ff74ef96 100644
--- a/tests/wpt/tests/tools/webdriver/webdriver/transport.py
+++ b/tests/wpt/tests/tools/webdriver/webdriver/transport.py
@@ -102,9 +102,9 @@ class HTTPWireProtocol:
Transports messages (commands and responses) over the WebDriver
wire protocol.
- Complex objects, such as ``webdriver.Element``, ``webdriver.Frame``,
- and ``webdriver.Window`` are by default not marshaled to enable
- use of `session.transport.send` in WPT tests::
+ Complex objects, such as ``webdriver.ShadowRoot``, ``webdriver.WebElement``,
+ ``webdriver.WebFrame``, and ``webdriver.WebWindow`` are by default not
+ marshaled to enable use of `session.transport.send` in WPT tests::
session = webdriver.Session("127.0.0.1", 4444)
response = transport.send("GET", "element/active", None)
@@ -180,17 +180,17 @@ class HTTPWireProtocol:
"""
Send a command to the remote.
- The request `body` must be JSON serialisable unless a
+ The request `body` must be JSON serializable unless a
custom `encoder` has been provided. This means complex
- objects such as ``webdriver.Element``, ``webdriver.Frame``,
- and `webdriver.Window`` are not automatically made
- into JSON. This behaviour is, however, provided by
+ objects such as ``webdriver.ShadowRoot``, ``webdriver.WebElement``,
+ ``webdriver.WebFrame``, and `webdriver.Window`` are not automatically
+ made into JSON. This behavior is, however, provided by
``webdriver.protocol.Encoder``, should you want it.
Similarly, the response body is returned au natural
as plain JSON unless a `decoder` that converts web
element references to ``webdriver.Element`` is provided.
- Use ``webdriver.protocol.Decoder`` to achieve this behaviour.
+ Use ``webdriver.protocol.Decoder`` to achieve this behavior.
The client will attempt to use persistent HTTP connections.
@@ -211,7 +211,7 @@ class HTTPWireProtocol:
describing the HTTP response received from the remote end.
:raises ValueError: If `body` or the response body are not
- JSON serialisable.
+ JSON serializable.
"""
if body is None and method == "POST":
body = {}
diff --git a/tests/wpt/tests/tools/wpt/utils.py b/tests/wpt/tests/tools/wpt/utils.py
index b015b95e1ae..5899dc3f3a9 100644
--- a/tests/wpt/tests/tools/wpt/utils.py
+++ b/tests/wpt/tests/tools/wpt/utils.py
@@ -3,10 +3,10 @@
import errno
import logging
import os
-import sys
import shutil
import stat
import subprocess
+import sys
import tarfile
import time
import zipfile
@@ -166,3 +166,16 @@ def sha256sum(file_path):
for chunk in iter(lambda: f.read(4096), b''):
hash.update(chunk)
return hash.hexdigest()
+
+
+# see https://docs.python.org/3/whatsnew/3.12.html#imp
+def load_source(modname, filename):
+ import importlib.machinery
+ import importlib.util
+
+ loader = importlib.machinery.SourceFileLoader(modname, filename)
+ spec = importlib.util.spec_from_file_location(modname, filename, loader=loader)
+ module = importlib.util.module_from_spec(spec)
+ sys.modules[module.__name__] = module
+ loader.exec_module(module)
+ return module
diff --git a/tests/wpt/tests/tools/wptrunner/requirements.txt b/tests/wpt/tests/tools/wptrunner/requirements.txt
index 1c4316a9f86..93c17bf3bff 100644
--- a/tests/wpt/tests/tools/wptrunner/requirements.txt
+++ b/tests/wpt/tests/tools/wptrunner/requirements.txt
@@ -7,4 +7,4 @@ packaging==23.1
pillow==9.5.0
requests==2.31.0
six==1.16.0
-urllib3==2.0.6
+urllib3==2.0.7
diff --git a/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/content_shell.py b/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/content_shell.py
index 14956eeb786..23f4e99da62 100644
--- a/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/content_shell.py
+++ b/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/content_shell.py
@@ -5,6 +5,7 @@ import os
import subprocess
from multiprocessing import Queue, Event
from threading import Thread
+from urllib.parse import urljoin
from . import chrome_spki_certs
from .base import (
@@ -16,6 +17,7 @@ from .base import (
from .base import get_timeout_multiplier # noqa: F401
from .chrome import debug_args
from ..executors import executor_kwargs as base_executor_kwargs
+from ..executors.base import server_url
from ..executors.executorcontentshell import ( # noqa: F401
ContentShellCrashtestExecutor,
ContentShellPrintRefTestExecutor,
@@ -82,7 +84,8 @@ def browser_kwargs(logger, test_type, run_info_data, config, subsuite, **kwargs)
return {"binary": kwargs["binary"],
"binary_args": args,
- "debug_info": kwargs["debug_info"]}
+ "debug_info": kwargs["debug_info"],
+ "pac_origin": server_url(config, "http")}
def executor_kwargs(logger, test_type, test_environment, run_info_data,
@@ -127,21 +130,27 @@ class ContentShellBrowser(Browser):
termination_timeout: float = 3
def __init__(self, logger, binary="content_shell", binary_args=None,
- debug_info=None, **kwargs):
+ debug_info=None, pac_origin=None, **kwargs):
super().__init__(logger)
- debug_cmd_prefix, browser_cmd = browser_command(binary, binary_args or [], debug_info)
- self._args = [*debug_cmd_prefix, *browser_cmd]
+ self._debug_cmd_prefix, self._browser_cmd = browser_command(
+ binary, binary_args or [], debug_info)
self._output_handler = None
self._proc = None
-
- def start(self, group_metadata, **kwargs):
- self.logger.debug("Starting content shell: %s..." % self._args[0])
- self._output_handler = OutputHandler(self.logger, self._args)
+ self._pac_origin = pac_origin
+ self._pac = None
+
+ def start(self, group_metadata, **settings):
+ browser_cmd, pac = list(self._browser_cmd), settings.get("pac")
+ if pac:
+ browser_cmd.insert(1, f"--proxy-pac-url={pac}")
+ self.logger.debug(f"Starting content shell: {browser_cmd[0]}...")
+ args = [*self._debug_cmd_prefix, *browser_cmd]
+ self._output_handler = OutputHandler(self.logger, args)
if os.name == "posix":
close_fds, preexec_fn = True, lambda: os.setpgid(0, 0)
else:
close_fds, preexec_fn = False, None
- self._proc = subprocess.Popen(self._args,
+ self._proc = subprocess.Popen(args,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
@@ -169,7 +178,7 @@ class ContentShellBrowser(Browser):
# Content shell is likely still in the process of initializing. The actual waiting
# for the startup to finish is done in the ContentShellProtocol.
self.logger.debug("Content shell has been started.")
- self._output_handler.start(group_metadata=group_metadata, **kwargs)
+ self._output_handler.start(group_metadata=group_metadata, **settings)
def stop(self, force=False):
self.logger.debug("Stopping content shell...")
@@ -239,6 +248,13 @@ class ContentShellBrowser(Browser):
def check_crash(self, process, test):
return not self.is_alive()
+ def settings(self, test):
+ pac_path = test.environment.get("pac")
+ if self._pac_origin and pac_path:
+ self._pac = urljoin(self._pac_origin, pac_path)
+ return {"pac": self._pac}
+ return {}
+
def _create_reader_thread(self, name, stream, queue, prefix=b""):
"""This creates (and starts) a background thread which reads lines from `stream` and
puts them into `queue` until `stream` reports EOF.
diff --git a/tests/wpt/tests/tools/wptrunner/wptrunner/executors/base.py b/tests/wpt/tests/tools/wptrunner/wptrunner/executors/base.py
index 1e66e60890e..e89b57b57ac 100644
--- a/tests/wpt/tests/tools/wptrunner/wptrunner/executors/base.py
+++ b/tests/wpt/tests/tools/wptrunner/wptrunner/executors/base.py
@@ -64,6 +64,16 @@ def strip_server(url):
return urlunsplit(url_parts)
+def server_url(server_config, protocol, subdomain=False):
+ scheme = "https" if protocol == "h2" else protocol
+ host = server_config["browser_host"]
+ if subdomain:
+ # The only supported subdomain filename flag is "www".
+ host = "{subdomain}.{host}".format(subdomain="www", host=host)
+ return "{scheme}://{host}:{port}".format(scheme=scheme, host=host,
+ port=server_config["ports"][protocol][0])
+
+
class TestharnessResultConverter:
harness_codes = {0: "OK",
1: "ERROR",
@@ -317,13 +327,7 @@ class TestExecutor:
self.runner.send_message("test_ended", test, result)
def server_url(self, protocol, subdomain=False):
- scheme = "https" if protocol == "h2" else protocol
- host = self.server_config["browser_host"]
- if subdomain:
- # The only supported subdomain filename flag is "www".
- host = "{subdomain}.{host}".format(subdomain="www", host=host)
- return "{scheme}://{host}:{port}".format(scheme=scheme, host=host,
- port=self.server_config["ports"][protocol][0])
+ return server_url(self.server_config, protocol, subdomain)
def test_url(self, test):
return urljoin(self.server_url(test.environment["protocol"],
diff --git a/tests/wpt/tests/tools/wptrunner/wptrunner/stability.py b/tests/wpt/tests/tools/wptrunner/wptrunner/stability.py
index 9ac6249c44c..029b237f988 100644
--- a/tests/wpt/tests/tools/wptrunner/wptrunner/stability.py
+++ b/tests/wpt/tests/tools/wptrunner/wptrunner/stability.py
@@ -2,7 +2,6 @@
import copy
import functools
-import imp
import io
import os
from collections import OrderedDict, defaultdict
@@ -10,16 +9,17 @@ from datetime import datetime
from mozlog import reader
from mozlog.formatters import JSONFormatter
-from mozlog.handlers import BaseHandler, StreamHandler, LogLevelFilter
+from mozlog.handlers import BaseHandler, LogLevelFilter, StreamHandler
+
+from tools.wpt.utils import load_source
from . import wptrunner
here = os.path.dirname(__file__)
-localpaths = imp.load_source("localpaths", os.path.abspath(os.path.join(here, os.pardir, os.pardir, "localpaths.py")))
+localpaths = load_source("localpaths", os.path.abspath(os.path.join(here, os.pardir, os.pardir, "localpaths.py"))) # type: ignore
from ci.tc.github_checks_output import get_gh_checks_outputter # type: ignore
from wpt.markdown import markdown_adjust, table # type: ignore
-
# If a test takes more than (FLAKY_THRESHOLD*timeout) and does not consistently
# time out, it is considered slow (potentially flaky).
FLAKY_THRESHOLD = 0.8
diff --git a/tests/wpt/tests/tools/wptrunner/wptrunner/testrunner.py b/tests/wpt/tests/tools/wptrunner/wptrunner/testrunner.py
index b84f1a52be3..a4f759c42a7 100644
--- a/tests/wpt/tests/tools/wptrunner/wptrunner/testrunner.py
+++ b/tests/wpt/tests/tools/wptrunner/wptrunner/testrunner.py
@@ -701,7 +701,7 @@ class TestRunnerManager(threading.Thread):
# change result to unexpected if expected_fail_message does not
# match
expected_fail_message = test.expected_fail_message(result.name)
- if expected_fail_message is not None and result.message != expected_fail_message:
+ if expected_fail_message is not None and result.message.strip() != expected_fail_message:
is_unexpected = True
if is_unexpected:
diff --git a/tests/wpt/tests/tools/wptrunner/wptrunner/tests/test_wptrunner.py b/tests/wpt/tests/tools/wptrunner/wptrunner/tests/test_wptrunner.py
new file mode 100644
index 00000000000..3c9a0bc1fd4
--- /dev/null
+++ b/tests/wpt/tests/tools/wptrunner/wptrunner/tests/test_wptrunner.py
@@ -0,0 +1,79 @@
+from ..wptrunner import get_pause_after_test
+from .test_testloader import Subsuite, TestFilter, TestLoader, WPTManifest
+
+def test_get_pause_after_test(): # type: ignore
+ manifest_json = {
+ "items": {
+ "testharness": {
+ "a": {
+ "foo.html": [
+ "abcdef123456",
+ [None, {}],
+ ],
+ "bar.h2.html": [
+ "uvwxyz987654",
+ [None, {}],
+ ],
+ }
+ },
+ "reftest": {
+ "a": {
+ "reffoo.html": [
+ "abcdef654321",
+ [None, [["/common/some-ref.html", "=="]], {}]
+ ],
+ }
+ }
+ },
+ "url_base": "/",
+ "version": 8,
+ }
+
+ kwargs = {
+ "pause_after_test": None,
+ "repeat_until_unexpected": False,
+ "headless": False,
+ "debug_test": False,
+ "repeat": 1,
+ "rerun": 1
+ }
+
+ manifest = WPTManifest.from_json("/", manifest_json)
+ test_manifests = {manifest: {"metadata_path": ""}}
+
+ manifest_filters = [TestFilter(test_manifests, include=["/a/foo.html", "/a/reffoo.html"])]
+
+ subsuites = {}
+ subsuites[""] = Subsuite("", config={})
+
+ # This has two testharness tests, so shouldn't set pause_after_test
+ loader = TestLoader(test_manifests, ["testharness"], None, subsuites)
+
+ assert get_pause_after_test(loader, **kwargs) is False
+
+ # This has one testharness test, so should set pause_after_test
+ loader = TestLoader(test_manifests, ["testharness"], None, subsuites,
+ manifest_filters=manifest_filters)
+
+ assert get_pause_after_test(loader, **kwargs) is True
+
+ # This has one testharness test, and one reftest so shouldn't set pause_after_test
+ loader = TestLoader(test_manifests, ["testharness", "reftest"], None, subsuites,
+ manifest_filters=manifest_filters)
+
+ assert get_pause_after_test(loader, **kwargs) is False
+
+ # This has one reftest so shouldn't set pause_after_test
+ loader = TestLoader(test_manifests, ["reftest"], None, subsuites)
+
+ assert get_pause_after_test(loader, **kwargs) is False
+
+ multi_subsuites = {}
+ multi_subsuites[""] = Subsuite("", config={})
+ multi_subsuites["extra"] = Subsuite("extra", config={}, include=["/a/foo.html"])
+
+ # This has one testharness test per subsuite, so shouldn't set pause_after_test
+ loader = TestLoader(test_manifests, ["testharness"], None, multi_subsuites,
+ manifest_filters=manifest_filters)
+ print(loader.tests)
+ assert get_pause_after_test(loader, **kwargs) is False
diff --git a/tests/wpt/tests/tools/wptrunner/wptrunner/wptrunner.py b/tests/wpt/tests/tools/wptrunner/wptrunner/wptrunner.py
index a4ad268dce1..b9e5190105c 100644
--- a/tests/wpt/tests/tools/wptrunner/wptrunner/wptrunner.py
+++ b/tests/wpt/tests/tools/wptrunner/wptrunner/wptrunner.py
@@ -159,20 +159,30 @@ def list_tests(test_paths, product, **kwargs):
def get_pause_after_test(test_loader, **kwargs):
- if kwargs["pause_after_test"] is None:
- if kwargs["repeat_until_unexpected"]:
- return False
- if kwargs["headless"]:
- return False
- if kwargs["debug_test"]:
- return True
- tests = test_loader.tests
- is_single_testharness = (sum(len(item) for item in tests.values()) == 1 and
- len(tests.get("testharness", [])) == 1)
- if kwargs["repeat"] == 1 and kwargs["rerun"] == 1 and is_single_testharness:
- return True
+ if kwargs["pause_after_test"] is not None:
+ return kwargs["pause_after_test"]
+ if kwargs["repeat_until_unexpected"]:
return False
- return kwargs["pause_after_test"]
+ if kwargs["headless"]:
+ return False
+ if kwargs["debug_test"]:
+ return True
+ tests = test_loader.tests
+ is_single_testharness = True
+ testharness_count = 0
+ for tests_by_type in tests.values():
+ for test_type, tests in tests_by_type.items():
+ if test_type != "testharness" and len(tests):
+ is_single_testharness = False
+ break
+ elif test_type == "testharness":
+ testharness_count += len(tests)
+ if testharness_count > 1:
+ is_single_testharness = False
+ break
+ return kwargs["repeat"] == 1 and kwargs["rerun"] == 1 and is_single_testharness
+
+
def log_suite_start(tests_by_group, base_run_info, subsuites, run_by_dir):
diff --git a/tests/wpt/tests/wai-aria/role/invalid-roles.html b/tests/wpt/tests/wai-aria/role/invalid-roles.html
index e16fb677044..3f4255083e1 100644
--- a/tests/wpt/tests/wai-aria/role/invalid-roles.html
+++ b/tests/wpt/tests/wai-aria/role/invalid-roles.html
@@ -39,7 +39,7 @@
<nav role="&#8203" data-testname="nav with zero-width space as role (should be treated as whitespace)" data-expectedrole="navigation" class="ex">x</nav>
<nav role="&#10240" data-testname="nav with braille space (10240) as role" data-expectedrole="navigation" class="ex">x</nav>
<nav role="&#x2800" data-testname="nav with braille space (x2800) as role" data-expectedrole="navigation" class="ex">x</nav>
-<nav role="&nbsp" data-testname="nav with non-breaking space (nbsp) as role" data-expectedrole="navigation" class="ex">x</nav>
+<nav role="&nbsp;" data-testname="nav with non-breaking space (nbsp) as role" data-expectedrole="navigation" class="ex">x</nav>
<nav role="&#20" data-testname="nav with standard space (nbsp) as role" data-expectedrole="navigation" class="ex">x</nav>
<!-- Escaped whitespace tests with <span> (including line breaks, tabs, zero-width space, braille space, non-breaking space, standard space) -->
@@ -49,7 +49,7 @@
<span role="&#8203" data-testname="span with escaped zero-width space as role (should be treated as whitespace)" class="ex-generic">x</span>
<span role="&#10240" data-testname="span with escaped braille space (10240) as role" class="ex-generic">x</span>
<span role="&#x2800" data-testname="span with escaped braille space (x2800) as role" class="ex-generic">x</span>
-<span role="&nbsp" data-testname="span with escaped non-breaking space (nbsp) as role" class="ex-generic">x</span>
+<span role="&nbsp;" data-testname="span with escaped non-breaking space (nbsp) as role" class="ex-generic">x</span>
<span role="&#20" data-testname="span with escaped standard space (nbsp) as role" class="ex-generic">x</span>
<!-- Unescaped whitespace tests with <span> (including line breaks, tabs, zero-width space, braille space, non-breaking space, standard space) -->
diff --git a/tests/wpt/tests/wasm/jsapi/exception/basic.tentative.any.js b/tests/wpt/tests/wasm/jsapi/exception/basic.tentative.any.js
index 869c64b6d30..cacce99d9cb 100644
--- a/tests/wpt/tests/wasm/jsapi/exception/basic.tentative.any.js
+++ b/tests/wpt/tests/wasm/jsapi/exception/basic.tentative.any.js
@@ -11,8 +11,7 @@ function assert_throws_wasm(fn, message) {
}
promise_test(async () => {
- const kWasmAnyRef = 0x6f;
- const kSig_v_r = makeSig([kWasmAnyRef], []);
+ const kSig_v_r = makeSig([kWasmExternRef], []);
const builder = new WasmModuleBuilder();
const tagIndex = builder.addTag(kSig_v_r);
builder.addFunction("throw_param", kSig_v_r)
@@ -48,7 +47,7 @@ promise_test(async () => {
const tagIndex = builder.addTag(kSig_v_a);
builder.addFunction("throw_null", kSig_v_v)
.addBody([
- kExprRefNull, kWasmAnyFunc,
+ kExprRefNull, kAnyFuncCode,
kExprThrow, tagIndex,
])
.exportFunc();
@@ -82,7 +81,7 @@ promise_test(async () => {
kExprCatch, tagIndex,
kExprReturn,
kExprEnd,
- kExprRefNull, kWasmAnyRef,
+ kExprRefNull, kExternRefCode,
])
.exportFunc();
@@ -106,7 +105,7 @@ promise_test(async () => {
kExprCatchAll,
kExprRethrow, 0x00,
kExprEnd,
- kExprRefNull, kWasmAnyRef,
+ kExprRefNull, kExternRefCode,
])
.exportFunc();
diff --git a/tests/wpt/tests/wasm/jsapi/gc/casts.tentative.any.js b/tests/wpt/tests/wasm/jsapi/gc/casts.tentative.any.js
new file mode 100644
index 00000000000..cce06224fd4
--- /dev/null
+++ b/tests/wpt/tests/wasm/jsapi/gc/casts.tentative.any.js
@@ -0,0 +1,332 @@
+// META: global=window,dedicatedworker,jsshell
+// META: script=/wasm/jsapi/wasm-module-builder.js
+
+let exports = {};
+setup(() => {
+ const builder = new WasmModuleBuilder();
+ const structIndex = builder.addStruct([makeField(kWasmI32, true)]);
+ const arrayIndex = builder.addArray(kWasmI32, true);
+ const structIndex2 = builder.addStruct([makeField(kWasmF32, true)]);
+ const arrayIndex2 = builder.addArray(kWasmF32, true);
+ const funcIndex = builder.addType({ params: [], results: [] });
+ const funcIndex2 = builder.addType({ params: [], results: [kWasmI32] });
+
+ const argFunctions = [
+ { name: "any", code: kWasmAnyRef },
+ { name: "eq", code: kWasmEqRef },
+ { name: "struct", code: kWasmStructRef },
+ { name: "array", code: kWasmArrayRef },
+ { name: "i31", code: kWasmI31Ref },
+ { name: "func", code: kWasmFuncRef },
+ { name: "extern", code: kWasmExternRef },
+ { name: "none", code: kWasmNullRef },
+ { name: "nofunc", code: kWasmNullFuncRef },
+ { name: "noextern", code: kWasmNullExternRef },
+ { name: "concreteStruct", code: structIndex },
+ { name: "concreteArray", code: arrayIndex },
+ { name: "concreteFunc", code: funcIndex },
+ ];
+
+ for (const desc of argFunctions) {
+ builder
+ .addFunction(desc.name + "Arg", makeSig_v_x(wasmRefType(desc.code)))
+ .addBody([])
+ .exportFunc();
+
+ builder
+ .addFunction(desc.name + "NullableArg", makeSig_v_x(wasmRefNullType(desc.code)))
+ .addBody([])
+ .exportFunc();
+ }
+
+ builder
+ .addFunction("makeStruct", makeSig_r_v(wasmRefType(structIndex)))
+ .addBody([...wasmI32Const(42),
+ ...GCInstr(kExprStructNew), structIndex])
+ .exportFunc();
+
+ builder
+ .addFunction("makeArray", makeSig_r_v(wasmRefType(arrayIndex)))
+ .addBody([...wasmI32Const(5), ...wasmI32Const(42),
+ ...GCInstr(kExprArrayNew), arrayIndex])
+ .exportFunc();
+
+ builder
+ .addFunction("makeStruct2", makeSig_r_v(wasmRefType(structIndex2)))
+ .addBody([...wasmF32Const(42),
+ ...GCInstr(kExprStructNew), structIndex2])
+ .exportFunc();
+
+ builder
+ .addFunction("makeArray2", makeSig_r_v(wasmRefType(arrayIndex2)))
+ .addBody([...wasmF32Const(42), ...wasmI32Const(5),
+ ...GCInstr(kExprArrayNew), arrayIndex2])
+ .exportFunc();
+
+ builder
+ .addFunction("testFunc", funcIndex)
+ .addBody([])
+ .exportFunc();
+
+ builder
+ .addFunction("testFunc2", funcIndex2)
+ .addBody([...wasmI32Const(42)])
+ .exportFunc();
+
+ const buffer = builder.toBuffer();
+ const module = new WebAssembly.Module(buffer);
+ const instance = new WebAssembly.Instance(module, {});
+ exports = instance.exports;
+});
+
+test(() => {
+ exports.anyArg(exports.makeStruct());
+ exports.anyArg(exports.makeArray());
+ exports.anyArg(42);
+ exports.anyArg(42n);
+ exports.anyArg("foo");
+ exports.anyArg({});
+ exports.anyArg(() => {});
+ exports.anyArg(exports.testFunc);
+ assert_throws_js(TypeError, () => exports.anyArg(null));
+
+ exports.anyNullableArg(null);
+ exports.anyNullableArg(exports.makeStruct());
+ exports.anyNullableArg(exports.makeArray());
+ exports.anyNullableArg(42);
+ exports.anyNullableArg(42n);
+ exports.anyNullableArg("foo");
+ exports.anyNullableArg({});
+ exports.anyNullableArg(() => {});
+ exports.anyNullableArg(exports.testFunc);
+}, "anyref casts");
+
+test(() => {
+ exports.eqArg(exports.makeStruct());
+ exports.eqArg(exports.makeArray());
+ exports.eqArg(42);
+ assert_throws_js(TypeError, () => exports.eqArg(42n));
+ assert_throws_js(TypeError, () => exports.eqArg("foo"));
+ assert_throws_js(TypeError, () => exports.eqArg({}));
+ assert_throws_js(TypeError, () => exports.eqArg(exports.testFunc));
+ assert_throws_js(TypeError, () => exports.eqArg(() => {}));
+ assert_throws_js(TypeError, () => exports.eqArg(null));
+
+ exports.eqNullableArg(null);
+ exports.eqNullableArg(exports.makeStruct());
+ exports.eqNullableArg(exports.makeArray());
+ exports.eqNullableArg(42);
+ assert_throws_js(TypeError, () => exports.eqNullableArg(42n));
+ assert_throws_js(TypeError, () => exports.eqNullableArg("foo"));
+ assert_throws_js(TypeError, () => exports.eqNullableArg({}));
+ assert_throws_js(TypeError, () => exports.eqNullableArg(exports.testFunc));
+ assert_throws_js(TypeError, () => exports.eqNullableArg(() => {}));
+}, "eqref casts");
+
+test(() => {
+ exports.structArg(exports.makeStruct());
+ assert_throws_js(TypeError, () => exports.structArg(exports.makeArray()));
+ assert_throws_js(TypeError, () => exports.structArg(42));
+ assert_throws_js(TypeError, () => exports.structArg(42n));
+ assert_throws_js(TypeError, () => exports.structArg("foo"));
+ assert_throws_js(TypeError, () => exports.structArg({}));
+ assert_throws_js(TypeError, () => exports.structArg(exports.testFunc));
+ assert_throws_js(TypeError, () => exports.structArg(() => {}));
+ assert_throws_js(TypeError, () => exports.structArg(null));
+
+ exports.structNullableArg(null);
+ exports.structNullableArg(exports.makeStruct());
+ assert_throws_js(TypeError, () => exports.structNullableArg(exports.makeArray()));
+ assert_throws_js(TypeError, () => exports.structNullableArg(42));
+ assert_throws_js(TypeError, () => exports.structNullableArg(42n));
+ assert_throws_js(TypeError, () => exports.structNullableArg("foo"));
+ assert_throws_js(TypeError, () => exports.structNullableArg({}));
+ assert_throws_js(TypeError, () => exports.structNullableArg(exports.testFunc));
+ assert_throws_js(TypeError, () => exports.structNullableArg(() => {}));
+}, "structref casts");
+
+test(() => {
+ exports.arrayArg(exports.makeArray());
+ assert_throws_js(TypeError, () => exports.arrayArg(exports.makeStruct()));
+ assert_throws_js(TypeError, () => exports.arrayArg(42));
+ assert_throws_js(TypeError, () => exports.arrayArg(42n));
+ assert_throws_js(TypeError, () => exports.arrayArg("foo"));
+ assert_throws_js(TypeError, () => exports.arrayArg({}));
+ assert_throws_js(TypeError, () => exports.arrayArg(exports.testFunc));
+ assert_throws_js(TypeError, () => exports.arrayArg(() => {}));
+ assert_throws_js(TypeError, () => exports.arrayArg(null));
+
+ exports.arrayNullableArg(null);
+ exports.arrayNullableArg(exports.makeArray());
+ assert_throws_js(TypeError, () => exports.arrayNullableArg(exports.makeStruct()));
+ assert_throws_js(TypeError, () => exports.arrayNullableArg(42));
+ assert_throws_js(TypeError, () => exports.arrayNullableArg(42n));
+ assert_throws_js(TypeError, () => exports.arrayNullableArg("foo"));
+ assert_throws_js(TypeError, () => exports.arrayNullableArg({}));
+ assert_throws_js(TypeError, () => exports.arrayNullableArg(exports.testFunc));
+ assert_throws_js(TypeError, () => exports.arrayNullableArg(() => {}));
+}, "arrayref casts");
+
+test(() => {
+ exports.i31Arg(42);
+ assert_throws_js(TypeError, () => exports.i31Arg(exports.makeStruct()));
+ assert_throws_js(TypeError, () => exports.i31Arg(exports.makeArray()));
+ assert_throws_js(TypeError, () => exports.i31Arg(42n));
+ assert_throws_js(TypeError, () => exports.i31Arg("foo"));
+ assert_throws_js(TypeError, () => exports.i31Arg({}));
+ assert_throws_js(TypeError, () => exports.i31Arg(exports.testFunc));
+ assert_throws_js(TypeError, () => exports.i31Arg(() => {}));
+ assert_throws_js(TypeError, () => exports.i31Arg(null));
+
+ exports.i31NullableArg(null);
+ exports.i31NullableArg(42);
+ assert_throws_js(TypeError, () => exports.i31NullableArg(exports.makeStruct()));
+ assert_throws_js(TypeError, () => exports.i31NullableArg(exports.makeArray()));
+ assert_throws_js(TypeError, () => exports.i31NullableArg(42n));
+ assert_throws_js(TypeError, () => exports.i31NullableArg("foo"));
+ assert_throws_js(TypeError, () => exports.i31NullableArg({}));
+ assert_throws_js(TypeError, () => exports.i31NullableArg(exports.testFunc));
+ assert_throws_js(TypeError, () => exports.i31NullableArg(() => {}));
+}, "i31ref casts");
+
+test(() => {
+ exports.funcArg(exports.testFunc);
+ assert_throws_js(TypeError, () => exports.funcArg(exports.makeStruct()));
+ assert_throws_js(TypeError, () => exports.funcArg(exports.makeArray()));
+ assert_throws_js(TypeError, () => exports.funcArg(42));
+ assert_throws_js(TypeError, () => exports.funcArg(42n));
+ assert_throws_js(TypeError, () => exports.funcArg("foo"));
+ assert_throws_js(TypeError, () => exports.funcArg({}));
+ assert_throws_js(TypeError, () => exports.funcArg(() => {}));
+ assert_throws_js(TypeError, () => exports.funcArg(null));
+
+ exports.funcNullableArg(null);
+ exports.funcNullableArg(exports.testFunc);
+ assert_throws_js(TypeError, () => exports.funcNullableArg(exports.makeStruct()));
+ assert_throws_js(TypeError, () => exports.funcNullableArg(exports.makeArray()));
+ assert_throws_js(TypeError, () => exports.funcNullableArg(42));
+ assert_throws_js(TypeError, () => exports.funcNullableArg(42n));
+ assert_throws_js(TypeError, () => exports.funcNullableArg("foo"));
+ assert_throws_js(TypeError, () => exports.funcNullableArg({}));
+ assert_throws_js(TypeError, () => exports.funcNullableArg(() => {}));
+}, "funcref casts");
+
+test(() => {
+ exports.externArg(exports.makeArray());
+ exports.externArg(exports.makeStruct());
+ exports.externArg(42);
+ exports.externArg(42n);
+ exports.externArg("foo");
+ exports.externArg({});
+ exports.externArg(exports.testFunc);
+ exports.externArg(() => {});
+ assert_throws_js(TypeError, () => exports.externArg(null));
+
+ exports.externNullableArg(null);
+ exports.externNullableArg(exports.makeArray());
+ exports.externNullableArg(exports.makeStruct());
+ exports.externNullableArg(42);
+ exports.externNullableArg(42n);
+ exports.externNullableArg("foo");
+ exports.externNullableArg({});
+ exports.externNullableArg(exports.testFunc);
+ exports.externNullableArg(() => {});
+}, "externref casts");
+
+test(() => {
+ for (const nullfunc of [exports.noneArg, exports.nofuncArg, exports.noexternArg]) {
+ assert_throws_js(TypeError, () => nullfunc(exports.makeStruct()));
+ assert_throws_js(TypeError, () => nullfunc(exports.makeArray()));
+ assert_throws_js(TypeError, () => nullfunc(42));
+ assert_throws_js(TypeError, () => nullfunc(42n));
+ assert_throws_js(TypeError, () => nullfunc("foo"));
+ assert_throws_js(TypeError, () => nullfunc({}));
+ assert_throws_js(TypeError, () => nullfunc(exports.testFunc));
+ assert_throws_js(TypeError, () => nullfunc(() => {}));
+ assert_throws_js(TypeError, () => nullfunc(null));
+ }
+
+ for (const nullfunc of [exports.noneNullableArg, exports.nofuncNullableArg, exports.noexternNullableArg]) {
+ nullfunc(null);
+ assert_throws_js(TypeError, () => nullfunc(exports.makeStruct()));
+ assert_throws_js(TypeError, () => nullfunc(exports.makeArray()));
+ assert_throws_js(TypeError, () => nullfunc(42));
+ assert_throws_js(TypeError, () => nullfunc(42n));
+ assert_throws_js(TypeError, () => nullfunc("foo"));
+ assert_throws_js(TypeError, () => nullfunc({}));
+ assert_throws_js(TypeError, () => nullfunc(exports.testFunc));
+ assert_throws_js(TypeError, () => nullfunc(() => {}));
+ }
+}, "null casts");
+
+test(() => {
+ exports.concreteStructArg(exports.makeStruct());
+ assert_throws_js(TypeError, () => exports.concreteStructArg(exports.makeStruct2()));
+ assert_throws_js(TypeError, () => exports.concreteStructArg(exports.makeArray()));
+ assert_throws_js(TypeError, () => exports.concreteStructArg(42));
+ assert_throws_js(TypeError, () => exports.concreteStructArg(42n));
+ assert_throws_js(TypeError, () => exports.concreteStructArg("foo"));
+ assert_throws_js(TypeError, () => exports.concreteStructArg({}));
+ assert_throws_js(TypeError, () => exports.concreteStructArg(exports.testFunc));
+ assert_throws_js(TypeError, () => exports.concreteStructArg(() => {}));
+ assert_throws_js(TypeError, () => exports.concreteStructArg(null));
+
+ exports.concreteStructNullableArg(null);
+ exports.concreteStructNullableArg(exports.makeStruct());
+ assert_throws_js(TypeError, () => exports.concreteStructNullableArg(exports.makeStruct2()));
+ assert_throws_js(TypeError, () => exports.concreteStructNullableArg(exports.makeArray()));
+ assert_throws_js(TypeError, () => exports.concreteStructNullableArg(42));
+ assert_throws_js(TypeError, () => exports.concreteStructNullableArg(42n));
+ assert_throws_js(TypeError, () => exports.concreteStructNullableArg("foo"));
+ assert_throws_js(TypeError, () => exports.concreteStructNullableArg({}));
+ assert_throws_js(TypeError, () => exports.concreteStructNullableArg(exports.testFunc));
+ assert_throws_js(TypeError, () => exports.concreteStructNullableArg(() => {}));
+}, "concrete struct casts");
+
+test(() => {
+ exports.concreteArrayArg(exports.makeArray());
+ assert_throws_js(TypeError, () => exports.concreteArrayArg(exports.makeArray2()));
+ assert_throws_js(TypeError, () => exports.concreteArrayArg(exports.makeStruct()));
+ assert_throws_js(TypeError, () => exports.concreteArrayArg(42));
+ assert_throws_js(TypeError, () => exports.concreteArrayArg(42n));
+ assert_throws_js(TypeError, () => exports.concreteArrayArg("foo"));
+ assert_throws_js(TypeError, () => exports.concreteArrayArg({}));
+ assert_throws_js(TypeError, () => exports.concreteArrayArg(exports.testFunc));
+ assert_throws_js(TypeError, () => exports.concreteArrayArg(() => {}));
+ assert_throws_js(TypeError, () => exports.concreteArrayArg(null));
+
+ exports.concreteArrayNullableArg(null);
+ exports.concreteArrayNullableArg(exports.makeArray());
+ assert_throws_js(TypeError, () => exports.concreteArrayNullableArg(exports.makeArray2()));
+ assert_throws_js(TypeError, () => exports.concreteArrayNullableArg(exports.makeStruct()));
+ assert_throws_js(TypeError, () => exports.concreteArrayNullableArg(42));
+ assert_throws_js(TypeError, () => exports.concreteArrayNullableArg(42n));
+ assert_throws_js(TypeError, () => exports.concreteArrayNullableArg("foo"));
+ assert_throws_js(TypeError, () => exports.concreteArrayNullableArg({}));
+ assert_throws_js(TypeError, () => exports.concreteArrayNullableArg(exports.testFunc));
+ assert_throws_js(TypeError, () => exports.concreteArrayNullableArg(() => {}));
+}, "concrete array casts");
+
+test(() => {
+ exports.concreteFuncArg(exports.testFunc);
+ assert_throws_js(TypeError, () => exports.concreteFuncArg(exports.testFunc2));
+ assert_throws_js(TypeError, () => exports.concreteFuncArg(exports.makeArray()));
+ assert_throws_js(TypeError, () => exports.concreteFuncArg(exports.makeStruct()));
+ assert_throws_js(TypeError, () => exports.concreteFuncArg(42));
+ assert_throws_js(TypeError, () => exports.concreteFuncArg(42n));
+ assert_throws_js(TypeError, () => exports.concreteFuncArg("foo"));
+ assert_throws_js(TypeError, () => exports.concreteFuncArg({}));
+ assert_throws_js(TypeError, () => exports.concreteFuncArg(() => {}));
+ assert_throws_js(TypeError, () => exports.concreteFuncArg(null));
+
+ exports.concreteFuncNullableArg(null);
+ exports.concreteFuncNullableArg(exports.testFunc);
+ assert_throws_js(TypeError, () => exports.concreteFuncNullableArg(exports.testFunc2));
+ assert_throws_js(TypeError, () => exports.concreteFuncNullableArg(exports.makeArray()));
+ assert_throws_js(TypeError, () => exports.concreteFuncNullableArg(exports.makeStruct()));
+ assert_throws_js(TypeError, () => exports.concreteFuncNullableArg(42));
+ assert_throws_js(TypeError, () => exports.concreteFuncNullableArg(42n));
+ assert_throws_js(TypeError, () => exports.concreteFuncNullableArg("foo"));
+ assert_throws_js(TypeError, () => exports.concreteFuncNullableArg({}));
+ assert_throws_js(TypeError, () => exports.concreteFuncNullableArg(() => {}));
+}, "concrete func casts");
diff --git a/tests/wpt/tests/wasm/jsapi/gc/exported-object.tentative.any.js b/tests/wpt/tests/wasm/jsapi/gc/exported-object.tentative.any.js
new file mode 100644
index 00000000000..b572f140067
--- /dev/null
+++ b/tests/wpt/tests/wasm/jsapi/gc/exported-object.tentative.any.js
@@ -0,0 +1,190 @@
+// META: global=window,dedicatedworker,jsshell
+// META: script=/wasm/jsapi/wasm-module-builder.js
+
+let functions = {};
+setup(() => {
+ const builder = new WasmModuleBuilder();
+
+ const structIndex = builder.addStruct([makeField(kWasmI32, true)]);
+ const arrayIndex = builder.addArray(kWasmI32, true);
+ const structRef = wasmRefType(structIndex);
+ const arrayRef = wasmRefType(arrayIndex);
+
+ builder
+ .addFunction("makeStruct", makeSig_r_v(structRef))
+ .addBody([...wasmI32Const(42),
+ ...GCInstr(kExprStructNew), structIndex])
+ .exportFunc();
+
+ builder
+ .addFunction("makeArray", makeSig_r_v(arrayRef))
+ .addBody([...wasmI32Const(5), ...wasmI32Const(42),
+ ...GCInstr(kExprArrayNew), arrayIndex])
+ .exportFunc();
+
+ const buffer = builder.toBuffer();
+ const module = new WebAssembly.Module(buffer);
+ const instance = new WebAssembly.Instance(module, {});
+ functions = instance.exports;
+});
+
+test(() => {
+ const struct = functions.makeStruct();
+ const array = functions.makeArray();
+ assert_equals(struct.foo, undefined);
+ assert_equals(struct[0], undefined);
+ assert_equals(array.foo, undefined);
+ assert_equals(array[0], undefined);
+}, "property access");
+
+test(() => {
+ "use strict";
+ const struct = functions.makeStruct();
+ const array = functions.makeArray();
+ assert_throws_js(TypeError, () => { struct.foo = 5; });
+ assert_throws_js(TypeError, () => { array.foo = 5; });
+ assert_throws_js(TypeError, () => { struct[0] = 5; });
+ assert_throws_js(TypeError, () => { array[0] = 5; });
+}, "property assignment (strict mode)");
+
+test(() => {
+ const struct = functions.makeStruct();
+ const array = functions.makeArray();
+ assert_throws_js(TypeError, () => { struct.foo = 5; });
+ assert_throws_js(TypeError, () => { array.foo = 5; });
+ assert_throws_js(TypeError, () => { struct[0] = 5; });
+ assert_throws_js(TypeError, () => { array[0] = 5; });
+}, "property assignment (non-strict mode)");
+
+test(() => {
+ const struct = functions.makeStruct();
+ const array = functions.makeArray();
+ assert_equals(Object.getOwnPropertyNames(struct).length, 0);
+ assert_equals(Object.getOwnPropertyNames(array).length, 0);
+}, "ownPropertyNames");
+
+test(() => {
+ const struct = functions.makeStruct();
+ const array = functions.makeArray();
+ assert_throws_js(TypeError, () => Object.defineProperty(struct, "foo", { value: 1 }));
+ assert_throws_js(TypeError, () => Object.defineProperty(array, "foo", { value: 1 }));
+}, "defineProperty");
+
+test(() => {
+ "use strict";
+ const struct = functions.makeStruct();
+ const array = functions.makeArray();
+ assert_throws_js(TypeError, () => delete struct.foo);
+ assert_throws_js(TypeError, () => delete struct[0]);
+ assert_throws_js(TypeError, () => delete array.foo);
+ assert_throws_js(TypeError, () => delete array[0]);
+}, "delete (strict mode)");
+
+test(() => {
+ const struct = functions.makeStruct();
+ const array = functions.makeArray();
+ assert_throws_js(TypeError, () => delete struct.foo);
+ assert_throws_js(TypeError, () => delete struct[0]);
+ assert_throws_js(TypeError, () => delete array.foo);
+ assert_throws_js(TypeError, () => delete array[0]);
+}, "delete (non-strict mode)");
+
+test(() => {
+ const struct = functions.makeStruct();
+ const array = functions.makeArray();
+ assert_equals(Object.getPrototypeOf(struct), null);
+ assert_equals(Object.getPrototypeOf(array), null);
+}, "getPrototypeOf");
+
+test(() => {
+ const struct = functions.makeStruct();
+ const array = functions.makeArray();
+ assert_throws_js(TypeError, () => Object.setPrototypeOf(struct, {}));
+ assert_throws_js(TypeError, () => Object.setPrototypeOf(array, {}));
+}, "setPrototypeOf");
+
+test(() => {
+ const struct = functions.makeStruct();
+ const array = functions.makeArray();
+ assert_false(Object.isExtensible(struct));
+ assert_false(Object.isExtensible(array));
+}, "isExtensible");
+
+test(() => {
+ const struct = functions.makeStruct();
+ const array = functions.makeArray();
+ assert_throws_js(TypeError, () => Object.preventExtensions(struct));
+ assert_throws_js(TypeError, () => Object.preventExtensions(array));
+}, "preventExtensions");
+
+test(() => {
+ const struct = functions.makeStruct();
+ const array = functions.makeArray();
+ assert_throws_js(TypeError, () => Object.seal(struct));
+ assert_throws_js(TypeError, () => Object.seal(array));
+}, "sealing");
+
+test(() => {
+ const struct = functions.makeStruct();
+ const array = functions.makeArray();
+ assert_equals(typeof struct, "object");
+ assert_equals(typeof array, "object");
+}, "typeof");
+
+test(() => {
+ const struct = functions.makeStruct();
+ const array = functions.makeArray();
+ assert_throws_js(TypeError, () => struct.toString());
+ assert_equals(Object.prototype.toString.call(struct), "[object Object]");
+ assert_throws_js(TypeError, () => array.toString());
+ assert_equals(Object.prototype.toString.call(array), "[object Object]");
+}, "toString");
+
+test(() => {
+ const struct = functions.makeStruct();
+ const array = functions.makeArray();
+ assert_throws_js(TypeError, () => struct.valueOf());
+ assert_equals(Object.prototype.valueOf.call(struct), struct);
+ assert_throws_js(TypeError, () => array.valueOf());
+ assert_equals(Object.prototype.valueOf.call(array), array);
+}, "valueOf");
+
+test(() => {
+ const struct = functions.makeStruct();
+ const array = functions.makeArray();
+ const map = new Map();
+ map.set(struct, "struct");
+ map.set(array, "array");
+ assert_equals(map.get(struct), "struct");
+ assert_equals(map.get(array), "array");
+}, "GC objects as map keys");
+
+test(() => {
+ const struct = functions.makeStruct();
+ const array = functions.makeArray();
+ const set = new Set();
+ set.add(struct);
+ set.add(array);
+ assert_true(set.has(struct));
+ assert_true(set.has(array));
+}, "GC objects as set element");
+
+test(() => {
+ const struct = functions.makeStruct();
+ const array = functions.makeArray();
+ const map = new WeakMap();
+ map.set(struct, "struct");
+ map.set(array, "array");
+ assert_equals(map.get(struct), "struct");
+ assert_equals(map.get(array), "array");
+}, "GC objects as weak map keys");
+
+test(() => {
+ const struct = functions.makeStruct();
+ const array = functions.makeArray();
+ const set = new WeakSet();
+ set.add(struct);
+ set.add(array);
+ assert_true(set.has(struct));
+ assert_true(set.has(array));
+}, "GC objects as weak set element");
diff --git a/tests/wpt/tests/wasm/jsapi/gc/i31.tentative.any.js b/tests/wpt/tests/wasm/jsapi/gc/i31.tentative.any.js
new file mode 100644
index 00000000000..17fd82440cc
--- /dev/null
+++ b/tests/wpt/tests/wasm/jsapi/gc/i31.tentative.any.js
@@ -0,0 +1,98 @@
+// META: global=window,dedicatedworker,jsshell
+// META: script=/wasm/jsapi/wasm-module-builder.js
+
+let exports = {};
+setup(() => {
+ const builder = new WasmModuleBuilder();
+ const i31Ref = wasmRefType(kWasmI31Ref);
+ const i31NullableRef = wasmRefNullType(kWasmI31Ref);
+ const anyRef = wasmRefType(kWasmAnyRef);
+
+ builder
+ .addFunction("makeI31", makeSig_r_x(i31Ref, kWasmI32))
+ .addBody([kExprLocalGet, 0,
+ ...GCInstr(kExprI31New)])
+ .exportFunc();
+
+ builder
+ .addFunction("castI31", makeSig_r_x(kWasmI32, anyRef))
+ .addBody([kExprLocalGet, 0,
+ ...GCInstr(kExprRefCast), kI31RefCode,
+ ...GCInstr(kExprI31GetU)])
+ .exportFunc();
+
+ builder
+ .addFunction("getI31", makeSig_r_x(kWasmI32, i31Ref))
+ .addBody([kExprLocalGet, 0,
+ ...GCInstr(kExprI31GetS)])
+ .exportFunc();
+
+ builder
+ .addFunction("argI31", makeSig_v_x(i31NullableRef))
+ .addBody([])
+ .exportFunc();
+
+ builder
+ .addGlobal(i31NullableRef, true, [...wasmI32Const(0), ...GCInstr(kExprI31New)])
+ builder
+ .addExportOfKind("i31Global", kExternalGlobal, 0);
+
+ builder
+ .addTable(i31NullableRef, 10)
+ builder
+ .addExportOfKind("i31Table", kExternalTable, 0);
+
+ const buffer = builder.toBuffer();
+ const module = new WebAssembly.Module(buffer);
+ const instance = new WebAssembly.Instance(module, {});
+ exports = instance.exports;
+});
+
+test(() => {
+ assert_equals(exports.makeI31(42), 42);
+ assert_equals(exports.makeI31(2 ** 30 - 1), 2 ** 30 - 1);
+ assert_equals(exports.makeI31(2 ** 30), -(2 ** 30));
+ assert_equals(exports.makeI31(-(2 ** 30)), -(2 ** 30));
+ assert_equals(exports.makeI31(2 ** 31 - 1), -1);
+ assert_equals(exports.makeI31(2 ** 31), 0);
+}, "i31ref conversion to Number");
+
+test(() => {
+ assert_equals(exports.getI31(exports.makeI31(42)), 42);
+ assert_equals(exports.getI31(42), 42);
+ assert_equals(exports.getI31(2.0 ** 30 - 1), 2 ** 30 - 1);
+ assert_equals(exports.getI31(-(2 ** 30)), -(2 ** 30));
+}, "Number conversion to i31ref");
+
+test(() => {
+ exports.argI31(null);
+ assert_throws_js(TypeError, () => exports.argI31(2 ** 30));
+ assert_throws_js(TypeError, () => exports.argI31(-(2 ** 30) - 1));
+ assert_throws_js(TypeError, () => exports.argI31(2n));
+ assert_throws_js(TypeError, () => exports.argI31(() => 3));
+ assert_throws_js(TypeError, () => exports.argI31(exports.getI31));
+}, "Check i31ref argument type");
+
+test(() => {
+ assert_equals(exports.castI31(42), 42);
+ assert_equals(exports.castI31(2 ** 30 - 1), 2 ** 30 - 1);
+ assert_throws_js(WebAssembly.RuntimeError, () => { exports.castI31(2 ** 30); });
+ assert_throws_js(WebAssembly.RuntimeError, () => { exports.castI31(-(2 ** 30) - 1); });
+ assert_throws_js(WebAssembly.RuntimeError, () => { exports.castI31(2 ** 32); });
+}, "Numbers in i31 range are i31ref, not hostref");
+
+test(() => {
+ assert_equals(exports.i31Global.value, 0);
+ exports.i31Global.value = 42;
+ assert_throws_js(TypeError, () => exports.i31Global.value = 2 ** 30);
+ assert_throws_js(TypeError, () => exports.i31Global.value = -(2 ** 30) - 1);
+ assert_equals(exports.i31Global.value, 42);
+}, "i31ref global");
+
+test(() => {
+ assert_equals(exports.i31Table.get(0), null);
+ exports.i31Table.set(0, 42);
+ assert_throws_js(TypeError, () => exports.i31Table.set(0, 2 ** 30));
+ assert_throws_js(TypeError, () => exports.i31Table.set(0, -(2 ** 30) - 1));
+ assert_equals(exports.i31Table.get(0), 42);
+}, "i31ref table");
diff --git a/tests/wpt/tests/wasm/jsapi/instanceTestFactory.js b/tests/wpt/tests/wasm/jsapi/instanceTestFactory.js
index 6e6ec875bda..2e015af8198 100644
--- a/tests/wpt/tests/wasm/jsapi/instanceTestFactory.js
+++ b/tests/wpt/tests/wasm/jsapi/instanceTestFactory.js
@@ -237,7 +237,7 @@ const instanceTestFactory = [
builder.addGlobal(kWasmI32, true)
.exportAs("")
- .init = 7;
+ .init = wasmI32Const(7);
const buffer = builder.toBuffer();
@@ -273,10 +273,10 @@ const instanceTestFactory = [
builder.addGlobal(kWasmI32, true)
.exportAs("global")
- .init = 7;
+ .init = wasmI32Const(7);
builder.addGlobal(kWasmF64, true)
.exportAs("global2")
- .init = 1.2;
+ .init = wasmF64Const(1.2);
builder.addMemory(4, 8, true);
diff --git a/tests/wpt/tests/wasm/jsapi/module/exports.any.js b/tests/wpt/tests/wasm/jsapi/module/exports.any.js
index 499a2649b17..0c32e984a2c 100644
--- a/tests/wpt/tests/wasm/jsapi/module/exports.any.js
+++ b/tests/wpt/tests/wasm/jsapi/module/exports.any.js
@@ -109,10 +109,10 @@ test(() => {
builder.addGlobal(kWasmI32, true)
.exportAs("global")
- .init = 7;
+ .init = wasmI32Const(7);
builder.addGlobal(kWasmF64, true)
.exportAs("global2")
- .init = 1.2;
+ .init = wasmF64Const(1.2);
builder.addMemory(0, 256, true);
@@ -167,7 +167,7 @@ test(() => {
builder.addGlobal(kWasmI32, true)
.exportAs("")
- .init = 7;
+ .init = wasmI32Const(7);
const buffer = builder.toBuffer()
const module = new WebAssembly.Module(buffer);
diff --git a/tests/wpt/tests/wasm/jsapi/wasm-module-builder.js b/tests/wpt/tests/wasm/jsapi/wasm-module-builder.js
index 3545c3a8da7..1d8db0a6e6f 100644
--- a/tests/wpt/tests/wasm/jsapi/wasm-module-builder.js
+++ b/tests/wpt/tests/wasm/jsapi/wasm-module-builder.js
@@ -74,6 +74,13 @@ let kLocalNamesCode = 2;
let kWasmFunctionTypeForm = 0x60;
let kWasmAnyFunctionTypeForm = 0x70;
+let kWasmStructTypeForm = 0x5f;
+let kWasmArrayTypeForm = 0x5e;
+let kWasmSubtypeForm = 0x50;
+let kWasmSubtypeFinalForm = 0x4f;
+let kWasmRecursiveTypeGroupForm = 0x4e;
+
+let kNoSuperType = 0xFFFFFFFF;
let kHasMaximumFlag = 1;
let kSharedHasMaximumFlag = 3;
@@ -97,8 +104,43 @@ let kWasmI64 = 0x7e;
let kWasmF32 = 0x7d;
let kWasmF64 = 0x7c;
let kWasmS128 = 0x7b;
-let kWasmAnyRef = 0x6f;
-let kWasmAnyFunc = 0x70;
+
+// These are defined as negative integers to distinguish them from positive type
+// indices.
+let kWasmNullFuncRef = -0x0d;
+let kWasmNullExternRef = -0x0e;
+let kWasmNullRef = -0x0f;
+let kWasmFuncRef = -0x10;
+let kWasmAnyFunc = kWasmFuncRef; // Alias named as in the JS API spec
+let kWasmExternRef = -0x11;
+let kWasmAnyRef = -0x12;
+let kWasmEqRef = -0x13;
+let kWasmI31Ref = -0x14;
+let kWasmStructRef = -0x15;
+let kWasmArrayRef = -0x16;
+
+// Use the positive-byte versions inside function bodies.
+let kLeb128Mask = 0x7f;
+let kFuncRefCode = kWasmFuncRef & kLeb128Mask;
+let kAnyFuncCode = kFuncRefCode; // Alias named as in the JS API spec
+let kExternRefCode = kWasmExternRef & kLeb128Mask;
+let kAnyRefCode = kWasmAnyRef & kLeb128Mask;
+let kEqRefCode = kWasmEqRef & kLeb128Mask;
+let kI31RefCode = kWasmI31Ref & kLeb128Mask;
+let kNullExternRefCode = kWasmNullExternRef & kLeb128Mask;
+let kNullFuncRefCode = kWasmNullFuncRef & kLeb128Mask;
+let kStructRefCode = kWasmStructRef & kLeb128Mask;
+let kArrayRefCode = kWasmArrayRef & kLeb128Mask;
+let kNullRefCode = kWasmNullRef & kLeb128Mask;
+
+let kWasmRefNull = 0x63;
+let kWasmRef = 0x64;
+function wasmRefNullType(heap_type) {
+ return {opcode: kWasmRefNull, heap_type: heap_type};
+}
+function wasmRefType(heap_type) {
+ return {opcode: kWasmRef, heap_type: heap_type};
+}
let kExternalFunction = 0;
let kExternalTable = 1;
@@ -146,14 +188,14 @@ let kSig_v_f = makeSig([kWasmF32], []);
let kSig_f_f = makeSig([kWasmF32], [kWasmF32]);
let kSig_f_d = makeSig([kWasmF64], [kWasmF32]);
let kSig_d_d = makeSig([kWasmF64], [kWasmF64]);
-let kSig_r_r = makeSig([kWasmAnyRef], [kWasmAnyRef]);
+let kSig_r_r = makeSig([kWasmExternRef], [kWasmExternRef]);
let kSig_a_a = makeSig([kWasmAnyFunc], [kWasmAnyFunc]);
-let kSig_i_r = makeSig([kWasmAnyRef], [kWasmI32]);
-let kSig_v_r = makeSig([kWasmAnyRef], []);
+let kSig_i_r = makeSig([kWasmExternRef], [kWasmI32]);
+let kSig_v_r = makeSig([kWasmExternRef], []);
let kSig_v_a = makeSig([kWasmAnyFunc], []);
-let kSig_v_rr = makeSig([kWasmAnyRef, kWasmAnyRef], []);
+let kSig_v_rr = makeSig([kWasmExternRef, kWasmExternRef], []);
let kSig_v_aa = makeSig([kWasmAnyFunc, kWasmAnyFunc], []);
-let kSig_r_v = makeSig([], [kWasmAnyRef]);
+let kSig_r_v = makeSig([], [kWasmExternRef]);
let kSig_a_v = makeSig([], [kWasmAnyFunc]);
let kSig_a_i = makeSig([kWasmI32], [kWasmAnyFunc]);
@@ -374,10 +416,50 @@ let kExprRefIsNull = 0xd1;
let kExprRefFunc = 0xd2;
// Prefix opcodes
+let kGCPrefix = 0xfb;
let kNumericPrefix = 0xfc;
let kSimdPrefix = 0xfd;
let kAtomicPrefix = 0xfe;
+// Use these for multi-byte instructions (opcode > 0x7F needing two LEB bytes):
+function GCInstr(opcode) {
+ if (opcode <= 0x7F) return [kGCPrefix, opcode];
+ return [kGCPrefix, 0x80 | (opcode & 0x7F), opcode >> 7];
+}
+
+// GC opcodes
+let kExprStructNew = 0x00;
+let kExprStructNewDefault = 0x01;
+let kExprStructGet = 0x02;
+let kExprStructGetS = 0x03;
+let kExprStructGetU = 0x04;
+let kExprStructSet = 0x05;
+let kExprArrayNew = 0x06;
+let kExprArrayNewDefault = 0x07;
+let kExprArrayNewFixed = 0x08;
+let kExprArrayNewData = 0x09;
+let kExprArrayNewElem = 0x0a;
+let kExprArrayGet = 0x0b;
+let kExprArrayGetS = 0x0c;
+let kExprArrayGetU = 0x0d;
+let kExprArraySet = 0x0e;
+let kExprArrayLen = 0x0f;
+let kExprArrayFill = 0x10;
+let kExprArrayCopy = 0x11;
+let kExprArrayInitData = 0x12;
+let kExprArrayInitElem = 0x13;
+let kExprRefTest = 0x14;
+let kExprRefTestNull = 0x15;
+let kExprRefCast = 0x16;
+let kExprRefCastNull = 0x17;
+let kExprBrOnCast = 0x18;
+let kExprBrOnCastFail = 0x19;
+let kExprExternInternalize = 0x1a;
+let kExprExternExternalize = 0x1b;
+let kExprI31New = 0x1c;
+let kExprI31GetS = 0x1d;
+let kExprI31GetU = 0x1e;
+
// Numeric opcodes.
let kExprMemoryInit = 0x08;
let kExprDataDrop = 0x09;
@@ -554,6 +636,25 @@ class Binary {
}
}
+ emit_heap_type(heap_type) {
+ this.emit_bytes(wasmSignedLeb(heap_type, kMaxVarInt32Size));
+ }
+
+ emit_type(type) {
+ if ((typeof type) == 'number') {
+ this.emit_u8(type >= 0 ? type : type & kLeb128Mask);
+ } else {
+ this.emit_u8(type.opcode);
+ if ('depth' in type) this.emit_u8(type.depth);
+ this.emit_heap_type(type.heap_type);
+ }
+ }
+
+ emit_init_expr(expr) {
+ this.emit_bytes(expr);
+ this.emit_u8(kExprEnd);
+ }
+
emit_header() {
this.emit_bytes([
kWasmH0, kWasmH1, kWasmH2, kWasmH3, kWasmV0, kWasmV1, kWasmV2, kWasmV3
@@ -644,11 +745,11 @@ class WasmFunctionBuilder {
}
class WasmGlobalBuilder {
- constructor(module, type, mutable) {
+ constructor(module, type, mutable, init) {
this.module = module;
this.type = type;
this.mutable = mutable;
- this.init = 0;
+ this.init = init;
}
exportAs(name) {
@@ -658,13 +759,24 @@ class WasmGlobalBuilder {
}
}
+function checkExpr(expr) {
+ for (let b of expr) {
+ if (typeof b !== 'number' || (b & (~0xFF)) !== 0) {
+ throw new Error(
+ 'invalid body (entries must be 8 bit numbers): ' + expr);
+ }
+ }
+}
+
class WasmTableBuilder {
- constructor(module, type, initial_size, max_size) {
+ constructor(module, type, initial_size, max_size, init_expr) {
this.module = module;
this.type = type;
this.initial_size = initial_size;
this.has_max = max_size != undefined;
this.max_size = max_size;
+ this.init_expr = init_expr;
+ this.has_init = init_expr !== undefined;
}
exportAs(name) {
@@ -674,6 +786,35 @@ class WasmTableBuilder {
}
}
+function makeField(type, mutability) {
+ if ((typeof mutability) != 'boolean') {
+ throw new Error('field mutability must be boolean');
+ }
+ return {type: type, mutability: mutability};
+}
+
+class WasmStruct {
+ constructor(fields, is_final, supertype_idx) {
+ if (!Array.isArray(fields)) {
+ throw new Error('struct fields must be an array');
+ }
+ this.fields = fields;
+ this.type_form = kWasmStructTypeForm;
+ this.is_final = is_final;
+ this.supertype = supertype_idx;
+ }
+}
+
+class WasmArray {
+ constructor(type, mutability, is_final, supertype_idx) {
+ this.type = type;
+ this.mutability = mutability;
+ this.type_form = kWasmArrayTypeForm;
+ this.is_final = is_final;
+ this.supertype = supertype_idx;
+ }
+}
+
class WasmModuleBuilder {
constructor() {
this.types = [];
@@ -686,6 +827,7 @@ class WasmModuleBuilder {
this.element_segments = [];
this.data_segments = [];
this.explicit = [];
+ this.rec_groups = [];
this.num_imported_funcs = 0;
this.num_imported_globals = 0;
this.num_imported_tables = 0;
@@ -728,25 +870,65 @@ class WasmModuleBuilder {
this.explicit.push(this.createCustomSection(name, bytes));
}
- addType(type) {
- this.types.push(type);
- var pl = type.params.length; // should have params
- var rl = type.results.length; // should have results
+ // We use {is_final = true} so that the MVP syntax is generated for
+ // signatures.
+ addType(type, supertype_idx = kNoSuperType, is_final = true) {
+ var pl = type.params.length; // should have params
+ var rl = type.results.length; // should have results
+ var type_copy = {params: type.params, results: type.results,
+ is_final: is_final, supertype: supertype_idx};
+ this.types.push(type_copy);
+ return this.types.length - 1;
+ }
+
+ addStruct(fields, supertype_idx = kNoSuperType, is_final = false) {
+ this.types.push(new WasmStruct(fields, is_final, supertype_idx));
return this.types.length - 1;
}
- addGlobal(local_type, mutable) {
- let glob = new WasmGlobalBuilder(this, local_type, mutable);
+ addArray(type, mutability, supertype_idx = kNoSuperType, is_final = false) {
+ this.types.push(new WasmArray(type, mutability, is_final, supertype_idx));
+ return this.types.length - 1;
+ }
+
+ static defaultFor(type) {
+ switch (type) {
+ case kWasmI32:
+ return wasmI32Const(0);
+ case kWasmI64:
+ return wasmI64Const(0);
+ case kWasmF32:
+ return wasmF32Const(0.0);
+ case kWasmF64:
+ return wasmF64Const(0.0);
+ case kWasmS128:
+ return [kSimdPrefix, kExprS128Const, ...(new Array(16).fill(0))];
+ default:
+ if ((typeof type) != 'number' && type.opcode != kWasmRefNull) {
+ throw new Error("Non-defaultable type");
+ }
+ let heap_type = (typeof type) == 'number' ? type : type.heap_type;
+ return [kExprRefNull, ...wasmSignedLeb(heap_type, kMaxVarInt32Size)];
+ }
+ }
+
+ addGlobal(type, mutable, init) {
+ if (init === undefined) init = WasmModuleBuilder.defaultFor(type);
+ checkExpr(init);
+ let glob = new WasmGlobalBuilder(this, type, mutable, init);
glob.index = this.globals.length + this.num_imported_globals;
this.globals.push(glob);
return glob;
}
- addTable(type, initial_size, max_size = undefined) {
- if (type != kWasmAnyRef && type != kWasmAnyFunc) {
- throw new Error('Tables must be of type kWasmAnyRef or kWasmAnyFunc');
+ addTable(type, initial_size, max_size = undefined, init_expr = undefined) {
+ if (type == kWasmI32 || type == kWasmI64 || type == kWasmF32 ||
+ type == kWasmF64 || type == kWasmS128 || type == kWasmStmt) {
+ throw new Error('Tables must be of a reference type');
}
- let table = new WasmTableBuilder(this, type, initial_size, max_size);
+ if (init_expr != undefined) checkExpr(init_expr);
+ let table = new WasmTableBuilder(
+ this, type, initial_size, max_size, init_expr);
table.index = this.tables.length + this.num_imported_tables;
this.tables.push(table);
return table;
@@ -754,9 +936,9 @@ class WasmModuleBuilder {
addTag(type) {
let type_index = (typeof type) == "number" ? type : this.addType(type);
- let except_index = this.tags.length + this.num_imported_tags;
+ let tag_index = this.tags.length + this.num_imported_tags;
this.tags.push(type_index);
- return except_index;
+ return tag_index;
}
addFunction(name, type) {
@@ -877,6 +1059,21 @@ class WasmModuleBuilder {
return this;
}
+ startRecGroup() {
+ this.rec_groups.push({start: this.types.length, size: 0});
+ }
+
+ endRecGroup() {
+ if (this.rec_groups.length == 0) {
+ throw new Error("Did not start a recursive group before ending one")
+ }
+ let last_element = this.rec_groups[this.rec_groups.length - 1]
+ if (last_element.size != 0) {
+ throw new Error("Did not start a recursive group before ending one")
+ }
+ last_element.size = this.types.length - last_element.start;
+ }
+
setName(name) {
this.name = name;
return this;
@@ -891,18 +1088,55 @@ class WasmModuleBuilder {
// Add type section
if (wasm.types.length > 0) {
- if (debug) print("emitting types @ " + binary.length);
+ if (debug) print('emitting types @ ' + binary.length);
binary.emit_section(kTypeSectionCode, section => {
- section.emit_u32v(wasm.types.length);
- for (let type of wasm.types) {
- section.emit_u8(kWasmFunctionTypeForm);
- section.emit_u32v(type.params.length);
- for (let param of type.params) {
- section.emit_u8(param);
+ let length_with_groups = wasm.types.length;
+ for (let group of wasm.rec_groups) {
+ length_with_groups -= group.size - 1;
+ }
+ section.emit_u32v(length_with_groups);
+
+ let rec_group_index = 0;
+
+ for (let i = 0; i < wasm.types.length; i++) {
+ if (rec_group_index < wasm.rec_groups.length &&
+ wasm.rec_groups[rec_group_index].start == i) {
+ section.emit_u8(kWasmRecursiveTypeGroupForm);
+ section.emit_u32v(wasm.rec_groups[rec_group_index].size);
+ rec_group_index++;
}
- section.emit_u32v(type.results.length);
- for (let result of type.results) {
- section.emit_u8(result);
+
+ let type = wasm.types[i];
+ if (type.supertype != kNoSuperType) {
+ section.emit_u8(type.is_final ? kWasmSubtypeFinalForm
+ : kWasmSubtypeForm);
+ section.emit_u8(1); // supertype count
+ section.emit_u32v(type.supertype);
+ } else if (!type.is_final) {
+ section.emit_u8(kWasmSubtypeForm);
+ section.emit_u8(0); // no supertypes
+ }
+ if (type instanceof WasmStruct) {
+ section.emit_u8(kWasmStructTypeForm);
+ section.emit_u32v(type.fields.length);
+ for (let field of type.fields) {
+ section.emit_type(field.type);
+ section.emit_u8(field.mutability ? 1 : 0);
+ }
+ } else if (type instanceof WasmArray) {
+ section.emit_u8(kWasmArrayTypeForm);
+ section.emit_type(type.type);
+ section.emit_u8(type.mutability ? 1 : 0);
+ } else {
+ section.emit_u8(kWasmFunctionTypeForm);
+ section.emit_u32v(type.params.length);
+ for (let param of type.params) {
+ section.emit_type(param);
+ }
+ section.emit_u32v(type.results.length);
+ for (let result of type.results) {
+ section.emit_type(result);
+ }
}
}
});
@@ -918,9 +1152,9 @@ class WasmModuleBuilder {
section.emit_string(imp.name || '');
section.emit_u8(imp.kind);
if (imp.kind == kExternalFunction) {
- section.emit_u32v(imp.type);
+ section.emit_u32v(imp.type_index);
} else if (imp.kind == kExternalGlobal) {
- section.emit_u32v(imp.type);
+ section.emit_type(imp.type);
section.emit_u8(imp.mutable);
} else if (imp.kind == kExternalMemory) {
var has_max = (typeof imp.maximum) != "undefined";
@@ -933,7 +1167,7 @@ class WasmModuleBuilder {
section.emit_u32v(imp.initial); // initial
if (has_max) section.emit_u32v(imp.maximum); // maximum
} else if (imp.kind == kExternalTable) {
- section.emit_u8(imp.type);
+ section.emit_type(imp.type);
var has_max = (typeof imp.maximum) != "undefined";
section.emit_u8(has_max ? 1 : 0); // flags
section.emit_u32v(imp.initial); // initial
@@ -965,10 +1199,11 @@ class WasmModuleBuilder {
binary.emit_section(kTableSectionCode, section => {
section.emit_u32v(wasm.tables.length);
for (let table of wasm.tables) {
- section.emit_u8(table.type);
+ section.emit_type(table.type);
section.emit_u8(table.has_max);
section.emit_u32v(table.initial_size);
if (table.has_max) section.emit_u32v(table.max_size);
+ if (table.has_init) section.emit_init_expr(table.init_expr);
}
});
}
@@ -997,41 +1232,9 @@ class WasmModuleBuilder {
binary.emit_section(kGlobalSectionCode, section => {
section.emit_u32v(wasm.globals.length);
for (let global of wasm.globals) {
- section.emit_u8(global.type);
+ section.emit_type(global.type);
section.emit_u8(global.mutable);
- if ((typeof global.init_index) == "undefined") {
- // Emit a constant initializer.
- switch (global.type) {
- case kWasmI32:
- section.emit_u8(kExprI32Const);
- section.emit_u32v(global.init);
- break;
- case kWasmI64:
- section.emit_u8(kExprI64Const);
- section.emit_u64v(global.init);
- break;
- case kWasmF32:
- section.emit_bytes(wasmF32Const(global.init));
- break;
- case kWasmF64:
- section.emit_bytes(wasmF64Const(global.init));
- break;
- case kWasmAnyFunc:
- case kWasmAnyRef:
- if (global.function_index !== undefined) {
- section.emit_u8(kExprRefFunc);
- section.emit_u32v(global.function_index);
- } else {
- section.emit_u8(kExprRefNull);
- }
- break;
- }
- } else {
- // Emit a global-index initializer.
- section.emit_u8(kExprGlobalGet);
- section.emit_u32v(global.init_index);
- }
- section.emit_u8(kExprEnd); // end of init expression
+ section.emit_init_expr(global.init);
}
});
}
@@ -1161,7 +1364,7 @@ class WasmModuleBuilder {
local_decls.push({count: l.s128_count, type: kWasmS128});
}
if (l.anyref_count > 0) {
- local_decls.push({count: l.anyref_count, type: kWasmAnyRef});
+ local_decls.push({count: l.anyref_count, type: kWasmExternRef});
}
if (l.anyfunc_count > 0) {
local_decls.push({count: l.anyfunc_count, type: kWasmAnyFunc});
@@ -1171,7 +1374,7 @@ class WasmModuleBuilder {
header.emit_u32v(local_decls.length);
for (let decl of local_decls) {
header.emit_u32v(decl.count);
- header.emit_u8(decl.type);
+ header.emit_type(decl.type);
}
section.emit_u32v(header.length + func.body.length);
diff --git a/tests/wpt/tests/web-animations/animation-model/animation-types/scrollbar-interpolation.html b/tests/wpt/tests/web-animations/animation-model/animation-types/scrollbar-interpolation.html
new file mode 100644
index 00000000000..bc02dd00b97
--- /dev/null
+++ b/tests/wpt/tests/web-animations/animation-model/animation-types/scrollbar-interpolation.html
@@ -0,0 +1,91 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<link rel="help" href="https://drafts.csswg.org/web-animations/#animation-types">
+<title>Scrollbar interpolation</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
+</head>
+<style type="text/css">
+ #container {
+ height: 100px;
+ width: 100px;
+ overflow: scroll;
+ }
+ #contents {
+ height: 200px;
+ width: 200px;
+ }
+</style>
+<body>
+ <div id="container">
+ <div id="contents"></div>
+ </div>
+</body>
+<!-- Extend coverage in interpolation-per-property-002 to include testing
+ if named and system colors
+-->
+<script type="text/javascript">
+ function interpolate(keyframes, property) {
+ const anim = container.animate(keyframes, {
+ duration: 1000,
+ easing: 'linear'
+ });
+ anim.pause();
+ anim.currentTime = 500;
+ const result = getComputedStyle(container)[property];
+ anim.cancel();
+ return result;
+ }
+
+ function test_scrollbar_interpolation(from, to) {
+ let fromKeyframe =`${from.thumb} ${from.track}`;
+ let toKeyframe = `${to.thumb} ${to.track}`;
+ let keyframes = { scrollbarColor: [ fromKeyframe, toKeyframe ] };
+ const scrollbarColors = interpolate(keyframes, 'scrollbarColor');
+
+ // As the colors may be system dependent, we use the container as a
+ // color swatch and resolve the color blend via background-color.
+ // The scrollbar colors are expected to match the blend on the thumb
+ // and track colors respectively.
+ keyframes = {
+ backgroundColor: [`${from.thumb}`, `${to.thumb}` ]
+ }
+ const expectedThumbColor = interpolate(keyframes, 'backgroundColor');
+ keyframes = {
+ backgroundColor: [ `${from.track}`, `${to.track}` ]
+ }
+ const expectedTrackColor = interpolate(keyframes, 'backgroundColor');
+ assert_equals(scrollbarColors,
+ `${expectedThumbColor} ${expectedTrackColor}`,
+ `${fromKeyframe} to ${toKeyframe}`);
+ }
+
+ test(() => {
+ const data = [
+ {
+ from: { thumb: 'black', track: 'white' },
+ to: { thumb: 'lime', track: 'darkgreen' }
+ },
+ {
+ from: { thumb: '#000', track: 'pink' },
+ to: { thumb: 'canvas', track: 'buttontext' }
+ },
+ {
+ from: { thumb: 'rgba(255,255,255,0)', track: 'rgba(128,128,128,0)'},
+ to: { thumb: 'rgba(255,255,255,1)', track: 'rgba(128,128,128,1)'}
+ },
+ {
+ from: { thumb: 'transparent', track: 'transparent' },
+ to: { thumb: 'rgba(255,255,255,1)', track: 'rgba(128,128,128,1)'}
+ }
+ ];
+ data.forEach((test) => {
+ test_scrollbar_interpolation(test.from, test.to);
+ });
+ }, 'Verify scrollbar-color-interpolation');
+</script>
+</html>
diff --git a/tests/wpt/tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-default-value.html b/tests/wpt/tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-default-value.html
deleted file mode 100644
index fe0cf15b43d..00000000000
--- a/tests/wpt/tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-default-value.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <title>
- audioparam-default-value.html
- </title>
- <script src="/resources/testharness.js"></script>
- <script src="/resources/testharnessreport.js"></script>
- <script src="/webaudio/resources/audit.js"></script>
- </head>
- <body>
- <script id="layout-test-code">
- const audit = Audit.createTaskRunner();
-
- audit.define('test', function(task, should) {
- const context = new OfflineAudioContext(1, 1, 44100);
- const defaultValue = -1;
- const gainNode = new GainNode(context, { gain: defaultValue });
-
- should(gainNode.gain.defaultValue, "AudioParam's defaultValue").beEqualTo(defaultValue);
-
- task.done();
- });
-
- audit.run();
- </script>
- </body>
-</html>
diff --git a/tests/wpt/tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-default-value.window.js b/tests/wpt/tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-default-value.window.js
new file mode 100644
index 00000000000..359df111846
--- /dev/null
+++ b/tests/wpt/tests/webaudio/the-audio-api/the-audioparam-interface/audioparam-default-value.window.js
@@ -0,0 +1,12 @@
+// META: script=/resources/testharness.js
+// META: script=/resources/testharnessreport.js
+
+'use strict';
+
+test(() => {
+ const context = new OfflineAudioContext(1, 1, 44100);
+ const defaultValue = -1;
+ const gainNode = new GainNode(context, { gain: defaultValue });
+
+ assert_equals(gainNode.gain.defaultValue, defaultValue, "AudioParam's defaultValue is not correct.");
+}, "AudioParam's defaultValue");
diff --git a/tests/wpt/tests/webauthn/storecredential.https.html b/tests/wpt/tests/webauthn/storecredential.https.html
new file mode 100644
index 00000000000..726b289fbd1
--- /dev/null
+++ b/tests/wpt/tests/webauthn/storecredential.https.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script src=helpers.js></script>
+<script>
+ "use strict";
+
+ virtualAuthenticatorPromiseTest(async t => {
+ const cred = await navigator.credentials.get({publicKey: {
+ challenge: new Uint8Array(),
+ allowCredentials: [{
+ id: (await createCredential()).rawId,
+ type: "public-key",
+ }],
+ }});
+ return promise_rejects_dom(t, "NotSupportedError", navigator.credentials.store(cred));
+ }, {}, "navigator.credentials.store() throws NotAllowedError with a public key credential");
+
+</script>
diff --git a/tests/wpt/tests/webcodecs/META.yml b/tests/wpt/tests/webcodecs/META.yml
index 8570ee05e5a..071ef88121b 100644
--- a/tests/wpt/tests/webcodecs/META.yml
+++ b/tests/wpt/tests/webcodecs/META.yml
@@ -3,3 +3,5 @@ suggested_reviewers:
- Djuffin
- sandersdan
- youennf
+ - padenot
+ - ChunMinChang
diff --git a/tests/wpt/tests/webcodecs/audio-decoder.https.any.js b/tests/wpt/tests/webcodecs/audio-decoder.https.any.js
index 606b052edc8..79ba22157ab 100644
--- a/tests/wpt/tests/webcodecs/audio-decoder.https.any.js
+++ b/tests/wpt/tests/webcodecs/audio-decoder.https.any.js
@@ -135,20 +135,23 @@ validButUnsupportedConfigs.forEach(entry => {
});
validButUnsupportedConfigs.forEach(entry => {
- async_test(
+ promise_test(
t => {
+ let isErrorCallbackCalled = false;
let codec = new AudioDecoder({
output: t.unreached_func('unexpected output'),
error: t.step_func_done(e => {
+ isErrorCallbackCalled = true;
assert_true(e instanceof DOMException);
assert_equals(e.name, 'NotSupportedError');
assert_equals(codec.state, 'closed', 'state');
})
});
codec.configure(entry.config);
- codec.flush()
+ return codec.flush()
.then(t.unreached_func('flush succeeded unexpectedly'))
.catch(t.step_func(e => {
+ assert_true(isErrorCallbackCalled, "isErrorCallbackCalled");
assert_true(e instanceof DOMException);
assert_equals(e.name, 'NotSupportedError');
assert_equals(codec.state, 'closed', 'state');
diff --git a/tests/wpt/tests/webcodecs/audio-encoder-config.https.any.js b/tests/wpt/tests/webcodecs/audio-encoder-config.https.any.js
index 98a9513b7dc..3be8eb3f6d3 100644
--- a/tests/wpt/tests/webcodecs/audio-encoder-config.https.any.js
+++ b/tests/wpt/tests/webcodecs/audio-encoder-config.https.any.js
@@ -213,20 +213,23 @@ validButUnsupportedConfigs.forEach(entry => {
});
validButUnsupportedConfigs.forEach(entry => {
- async_test(
+ promise_test(
t => {
+ let isErrorCallbackCalled = false;
let codec = new AudioEncoder({
output: t.unreached_func('unexpected output'),
error: t.step_func_done(e => {
+ isErrorCallbackCalled = true;
assert_true(e instanceof DOMException);
assert_equals(e.name, 'NotSupportedError');
assert_equals(codec.state, 'closed', 'state');
})
});
codec.configure(entry.config);
- codec.flush()
+ return codec.flush()
.then(t.unreached_func('flush succeeded unexpectedly'))
.catch(t.step_func(e => {
+ assert_true(isErrorCallbackCalled, "isErrorCallbackCalled");
assert_true(e instanceof DOMException);
assert_equals(e.name, 'NotSupportedError');
assert_equals(codec.state, 'closed', 'state');
diff --git a/tests/wpt/tests/webcodecs/video-decoder.https.any.js b/tests/wpt/tests/webcodecs/video-decoder.https.any.js
index 190a524dd6c..77a610bd4ea 100644
--- a/tests/wpt/tests/webcodecs/video-decoder.https.any.js
+++ b/tests/wpt/tests/webcodecs/video-decoder.https.any.js
@@ -96,20 +96,23 @@ validButUnsupportedConfigs.forEach(entry => {
});
validButUnsupportedConfigs.forEach(entry => {
- async_test(
+ promise_test(
t => {
+ let isErrorCallbackCalled = false;
let codec = new VideoDecoder({
output: t.unreached_func('unexpected output'),
- error: t.step_func_done(e => {
+ error: t.step_func(e => {
+ isErrorCallbackCalled = true;
assert_true(e instanceof DOMException);
assert_equals(e.name, 'NotSupportedError');
assert_equals(codec.state, 'closed', 'state');
})
});
codec.configure(entry.config);
- codec.flush()
+ return codec.flush()
.then(t.unreached_func('flush succeeded unexpectedly'))
.catch(t.step_func(e => {
+ assert_true(isErrorCallbackCalled, "isErrorCallbackCalled");
assert_true(e instanceof DOMException);
assert_equals(e.name, 'NotSupportedError');
assert_equals(codec.state, 'closed', 'state');
diff --git a/tests/wpt/tests/webcodecs/video-encoder-config.https.any.js b/tests/wpt/tests/webcodecs/video-encoder-config.https.any.js
index e4807361fca..5011bfdd0a8 100644
--- a/tests/wpt/tests/webcodecs/video-encoder-config.https.any.js
+++ b/tests/wpt/tests/webcodecs/video-encoder-config.https.any.js
@@ -189,20 +189,23 @@ validButUnsupportedConfigs.forEach(entry => {
});
validButUnsupportedConfigs.forEach(entry => {
- async_test(
+ promise_test(
t => {
+ let isErrorCallbackCalled = false;
let codec = new VideoEncoder({
output: t.unreached_func('unexpected output'),
error: t.step_func_done(e => {
+ isErrorCallbackCalled = true;
assert_true(e instanceof DOMException);
assert_equals(e.name, 'NotSupportedError');
assert_equals(codec.state, 'closed', 'state');
})
});
codec.configure(entry.config);
- codec.flush()
+ return codec.flush()
.then(t.unreached_func('flush succeeded unexpectedly'))
.catch(t.step_func(e => {
+ assert_true(isErrorCallbackCalled, "isErrorCallbackCalled");
assert_true(e instanceof DOMException);
assert_equals(e.name, 'NotSupportedError');
assert_equals(codec.state, 'closed', 'state');
diff --git a/tests/wpt/tests/webdriver/tests/bidi/browsing_context/context_destroyed/__init__.py b/tests/wpt/tests/webdriver/tests/bidi/browsing_context/context_destroyed/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/tests/wpt/tests/webdriver/tests/bidi/browsing_context/context_destroyed/__init__.py
diff --git a/tests/wpt/tests/webdriver/tests/bidi/browsing_context/context_destroyed/context_destroyed.py b/tests/wpt/tests/webdriver/tests/bidi/browsing_context/context_destroyed/context_destroyed.py
new file mode 100644
index 00000000000..5baac7abd2d
--- /dev/null
+++ b/tests/wpt/tests/webdriver/tests/bidi/browsing_context/context_destroyed/context_destroyed.py
@@ -0,0 +1,248 @@
+import pytest
+from webdriver.bidi.modules.script import ContextTarget
+from webdriver.error import TimeoutException
+
+from tests.support.sync import AsyncPoll
+from .. import assert_browsing_context
+
+pytestmark = pytest.mark.asyncio
+
+CONTEXT_DESTROYED_EVENT = "browsingContext.contextDestroyed"
+
+
+async def test_unsubscribe(bidi_session, new_tab):
+ await bidi_session.session.subscribe(events=[CONTEXT_DESTROYED_EVENT])
+ await bidi_session.session.unsubscribe(events=[CONTEXT_DESTROYED_EVENT])
+
+ # Track all received browsingContext.contextDestroyed events in the events array
+ events = []
+
+ async def on_event(_, data):
+ events.append(data)
+
+ remove_listener = bidi_session.add_event_listener(CONTEXT_DESTROYED_EVENT, on_event)
+
+ await bidi_session.browsing_context.close(context=new_tab["context"])
+
+ wait = AsyncPoll(bidi_session, timeout=0.5)
+ with pytest.raises(TimeoutException):
+ await wait.until(lambda _: len(events) > 0)
+
+ remove_listener()
+
+
+@pytest.mark.parametrize("type_hint", ["tab", "window"])
+async def test_new_context(bidi_session, wait_for_event, subscribe_events, type_hint):
+ await subscribe_events([CONTEXT_DESTROYED_EVENT])
+
+ on_entry = wait_for_event(CONTEXT_DESTROYED_EVENT)
+ new_context = await bidi_session.browsing_context.create(type_hint=type_hint)
+
+ await bidi_session.browsing_context.close(context=new_context["context"])
+
+ context_info = await on_entry
+
+ assert_browsing_context(
+ context_info,
+ new_context["context"],
+ children=None,
+ url="about:blank",
+ parent=None,
+ )
+
+
+@pytest.mark.parametrize("domain", ["", "alt"], ids=["same_origin", "cross_origin"])
+async def test_navigate(bidi_session, subscribe_events, new_tab, inline, domain):
+ await subscribe_events([CONTEXT_DESTROYED_EVENT])
+
+ # Track all received browsingContext.contextDestroyed events in the events array
+ events = []
+
+ async def on_event(_, data):
+ events.append(data)
+
+ remove_listener = bidi_session.add_event_listener(CONTEXT_DESTROYED_EVENT, on_event)
+
+ url = inline(f"<div>test</div>", domain=domain)
+ await bidi_session.browsing_context.navigate(
+ url=url, context=new_tab["context"], wait="complete"
+ )
+
+ # Make sure navigation doesn't cause the context to be destroyed
+ wait = AsyncPoll(bidi_session, timeout=0.5)
+ with pytest.raises(TimeoutException):
+ await wait.until(lambda _: len(events) > 0)
+
+ remove_listener()
+
+
+@pytest.mark.parametrize("domain", ["", "alt"], ids=["same_origin", "cross_origin"])
+async def test_navigate_iframe(
+ bidi_session, wait_for_event, subscribe_events, new_tab, inline, domain
+):
+ await subscribe_events([CONTEXT_DESTROYED_EVENT])
+
+ on_entry = wait_for_event(CONTEXT_DESTROYED_EVENT)
+
+ frame_url = inline("<div>foo</div>")
+ url = inline(f"<iframe src='{frame_url}'></iframe>")
+ await bidi_session.browsing_context.navigate(
+ url=url, context=new_tab["context"], wait="complete"
+ )
+
+ contexts = await bidi_session.browsing_context.get_tree(root=new_tab["context"])
+ frame = contexts[0]["children"][0]
+
+ # Navigate to destroy iframes
+ url = inline(f"<iframe src='{frame_url}'></iframe>", domain=domain)
+ await bidi_session.browsing_context.navigate(
+ url=url, context=new_tab["context"], wait="complete"
+ )
+
+ context_info = await on_entry
+
+ assert_browsing_context(
+ context_info,
+ frame["context"],
+ children=None,
+ url=frame_url,
+ parent=new_tab["context"],
+ )
+
+
+async def test_delete_iframe(
+ bidi_session, wait_for_event, subscribe_events, new_tab, inline
+):
+ await subscribe_events([CONTEXT_DESTROYED_EVENT])
+
+ on_entry = wait_for_event(CONTEXT_DESTROYED_EVENT)
+
+ frame_url = inline("<div>foo</div>")
+ url = inline(f"<iframe src='{frame_url}'></iframe>")
+ await bidi_session.browsing_context.navigate(
+ url=url, context=new_tab["context"], wait="complete"
+ )
+
+ contexts = await bidi_session.browsing_context.get_tree(root=new_tab["context"])
+ iframe = contexts[0]["children"][0]
+
+ # Delete the iframe
+ await bidi_session.script.evaluate(
+ expression="""document.querySelector('iframe').remove()""",
+ target=ContextTarget(new_tab["context"]),
+ await_promise=False,
+ )
+
+ context_info = await on_entry
+
+ assert_browsing_context(
+ context_info,
+ iframe["context"],
+ children=None,
+ url=frame_url,
+ parent=new_tab["context"],
+ )
+
+
+async def test_delete_nested_iframes(
+ bidi_session,
+ subscribe_events,
+ new_tab,
+ test_page_nested_frames,
+ test_page_same_origin_frame,
+):
+ await subscribe_events([CONTEXT_DESTROYED_EVENT])
+ # Track all received browsingContext.contextDestroyed events in the events array
+ events = []
+
+ async def on_event(_, data):
+ events.append(data)
+
+ remove_listener = bidi_session.add_event_listener(CONTEXT_DESTROYED_EVENT, on_event)
+
+ await bidi_session.browsing_context.navigate(
+ url=test_page_nested_frames, context=new_tab["context"], wait="complete"
+ )
+
+ contexts = await bidi_session.browsing_context.get_tree(root=new_tab["context"])
+ top_iframe = contexts[0]["children"][0]
+
+ # Delete top iframe
+ await bidi_session.script.evaluate(
+ expression="""document.querySelector('iframe').remove()""",
+ target=ContextTarget(new_tab["context"]),
+ await_promise=False,
+ )
+
+ assert len(events) == 1
+ assert_browsing_context(
+ events[0],
+ top_iframe["context"],
+ children=None,
+ url=test_page_same_origin_frame,
+ parent=new_tab["context"],
+ )
+
+ remove_listener()
+
+
+async def test_iframe_destroy_parent(
+ bidi_session, subscribe_events, new_tab, test_page_nested_frames
+):
+ await subscribe_events([CONTEXT_DESTROYED_EVENT])
+ # Track all received browsingContext.contextDestroyed events in the events array
+ events = []
+
+ async def on_event(_, data):
+ events.append(data)
+
+ remove_listener = bidi_session.add_event_listener(CONTEXT_DESTROYED_EVENT, on_event)
+
+ await bidi_session.browsing_context.navigate(
+ url=test_page_nested_frames, context=new_tab["context"], wait="complete"
+ )
+
+ # Destroy top context
+ await bidi_session.browsing_context.close(context=new_tab["context"])
+
+ assert len(events) == 1
+ assert_browsing_context(
+ events[0],
+ new_tab["context"],
+ children=None,
+ url=test_page_nested_frames,
+ parent=None,
+ )
+
+ remove_listener()
+
+
+async def test_subscribe_to_one_context(bidi_session, subscribe_events, new_tab):
+ # Subscribe to a specific context
+ await subscribe_events(
+ events=[CONTEXT_DESTROYED_EVENT], contexts=[new_tab["context"]]
+ )
+
+ # Track all received browsingContext.contextDestroyed events in the events array
+ events = []
+
+ async def on_event(_, data):
+ events.append(data)
+
+ remove_listener = bidi_session.add_event_listener(CONTEXT_DESTROYED_EVENT, on_event)
+
+ another_new_tab = await bidi_session.browsing_context.create(type_hint="tab")
+ await bidi_session.browsing_context.close(context=another_new_tab["context"])
+
+ # Make sure we didn't receive the event for the new tab
+ wait = AsyncPoll(bidi_session, timeout=0.5)
+ with pytest.raises(TimeoutException):
+ await wait.until(lambda _: len(events) > 0)
+
+ await bidi_session.browsing_context.close(context=new_tab["context"])
+
+ # Make sure we received the event
+ await wait.until(lambda _: len(events) >= 1)
+ assert len(events) == 1
+
+ remove_listener()
diff --git a/tests/wpt/tests/webdriver/tests/bidi/browsing_context/user_prompt_opened/user_prompt_opened.py b/tests/wpt/tests/webdriver/tests/bidi/browsing_context/user_prompt_opened/user_prompt_opened.py
index a24a1e86aba..a2d5d840a49 100644
--- a/tests/wpt/tests/webdriver/tests/bidi/browsing_context/user_prompt_opened/user_prompt_opened.py
+++ b/tests/wpt/tests/webdriver/tests/bidi/browsing_context/user_prompt_opened/user_prompt_opened.py
@@ -56,29 +56,40 @@ async def test_prompt_type(
}
+@pytest.mark.parametrize(
+ "default", [None, "", "default"], ids=["null", "empty string", "non empty string"]
+)
async def test_prompt_default_value(
- bidi_session, inline, new_tab, subscribe_events, wait_for_event
+ bidi_session, inline, new_tab, subscribe_events, wait_for_event, default
):
await subscribe_events(events=[USER_PROMPT_OPENED_EVENT])
on_entry = wait_for_event(USER_PROMPT_OPENED_EVENT)
text = "test"
- default = "default"
+
+ if default is None:
+ script = f"<script>window.prompt('{text}', null)</script>"
+ else:
+ script = f"<script>window.prompt('{text}', '{default}')</script>"
await bidi_session.browsing_context.navigate(
context=new_tab["context"],
- url=inline(f"<script>window.prompt('{text}', '{default}')</script>"),
+ url=inline(script),
)
event = await on_entry
- assert event == {
+ expected_event = {
"context": new_tab["context"],
"type": "prompt",
"message": text,
- "defaultValue": default,
}
+ if default is not None:
+ expected_event["defaultValue"] = default
+
+ assert event == expected_event
+
@pytest.mark.parametrize("type_hint", ["tab", "window"])
async def test_subscribe_to_one_context(
diff --git a/tests/wpt/tests/webdriver/tests/bidi/script/call_function/result_node.py b/tests/wpt/tests/webdriver/tests/bidi/script/call_function/result_node.py
index 9d09b9fc04a..47cbd42d22d 100644
--- a/tests/wpt/tests/webdriver/tests/bidi/script/call_function/result_node.py
+++ b/tests/wpt/tests/webdriver/tests/bidi/script/call_function/result_node.py
@@ -506,34 +506,147 @@ async def test_document_fragment_node(
@pytest.mark.asyncio
-async def test_node_within_object(bidi_session, get_test_page, top_context):
+@pytest.mark.parametrize(
+ "function_declaration, expected",
+ [
+ (
+ """
+ () => [document.querySelector("img")]
+ """,
+ {
+ "type": "array",
+ "value": [
+ {
+ "type": "node",
+ "sharedId": any_string,
+ "value": {
+ "attributes": {},
+ "childNodeCount": 0,
+ "localName": "img",
+ "namespaceURI": "http://www.w3.org/1999/xhtml",
+ "nodeType": 1,
+ },
+ },
+ ],
+ },
+ ),
+ (
+ """
+ () => {
+ const map = new Map();
+ map.set(document.querySelector("img"), "elem");
+ return map;
+ }
+ """,
+ {
+ "type": "map",
+ "value": [[
+ {
+ "type": "node",
+ "sharedId": any_string,
+ "value": {
+ "attributes": {},
+ "childNodeCount": 0,
+ "localName": "img",
+ "namespaceURI": "http://www.w3.org/1999/xhtml",
+ "nodeType": 1
+ }
+ },
+ {
+ "type": "string",
+ "value": "elem"
+ }
+ ]]
+ }
+ ),
+ (
+ """
+ () => {
+ const map = new Map();
+ map.set("elem", document.querySelector("img"));
+ return map;
+ }
+ """,
+ {
+ "type": "map",
+ "value": [[
+ "elem", {
+ "type": "node",
+ "sharedId": any_string,
+ "value": {
+ "attributes": {},
+ "childNodeCount": 0,
+ "localName": "img",
+ "namespaceURI": "http://www.w3.org/1999/xhtml",
+ "nodeType": 1
+ }
+ }
+ ]]
+ }
+ ),
+ (
+ """
+ () => ({"elem": document.querySelector("img")})
+ """,
+ {
+ "type": "object",
+ "value": [
+ ["elem", {
+ "type": "node",
+ "sharedId": any_string,
+ "value": {
+ "attributes": {},
+ "childNodeCount": 0,
+ "localName": "img",
+ "namespaceURI": "http://www.w3.org/1999/xhtml",
+ "nodeType": 1
+ }
+ }]
+ ]
+ }
+ ),
+ (
+ """
+ () => {
+ const set = new Set();
+ set.add(document.querySelector("img"));
+ return set;
+ }
+ """,
+ {
+ "type": "set",
+ "value": [
+ {
+ "type": "node",
+ "sharedId": any_string,
+ "value": {
+ "attributes": {},
+ "childNodeCount": 0,
+ "localName": "img",
+ "namespaceURI": "http://www.w3.org/1999/xhtml",
+ "nodeType": 1,
+ },
+ },
+ ],
+ },
+ ),
+ ], ids=[
+ "array", "map-key", "map-value", "object", "set"
+ ]
+)
+async def test_node_embedded_within(
+ bidi_session, get_test_page, top_context, function_declaration, expected
+):
await bidi_session.browsing_context.navigate(
context=top_context['context'], url=get_test_page(), wait="complete"
)
result = await bidi_session.script.call_function(
- function_declaration="""() => ({"elem": document.querySelector("img")})""",
+ function_declaration=function_declaration,
target=ContextTarget(top_context["context"]),
await_promise=False,
)
- expected = {
- "type": "object",
- "value": [
- ["elem", {
- "type": "node",
- "sharedId": any_string,
- "value": {
- "attributes": {},
- "childNodeCount": 0,
- "localName": "img",
- "namespaceURI": "http://www.w3.org/1999/xhtml",
- "nodeType": 1
- }
- }]
- ]
- }
-
recursive_compare(expected, result)
diff --git a/tests/wpt/tests/webdriver/tests/bidi/script/classic_interop/node_shared_id.py b/tests/wpt/tests/webdriver/tests/bidi/script/classic_interop/node_shared_id.py
index 82b39b42e1c..aeb2bc45978 100644
--- a/tests/wpt/tests/webdriver/tests/bidi/script/classic_interop/node_shared_id.py
+++ b/tests/wpt/tests/webdriver/tests/bidi/script/classic_interop/node_shared_id.py
@@ -1,6 +1,6 @@
import pytest
-from webdriver import Element, ShadowRoot
+from webdriver import ShadowRoot, WebElement
from webdriver.bidi.modules.script import ContextTarget
pytestmark = pytest.mark.asyncio
@@ -51,7 +51,7 @@ async def test_web_element_reference_created_in_bidi(
assert nodeType == ELEMENT_NODE
# Use element reference from WebDriver BiDi in WebDriver classic
- node = Element(current_session, result["sharedId"])
+ node = WebElement(current_session, result["sharedId"])
nodeType = current_session.execute_script(
"""return arguments[0].nodeType""", args=(node,)
)
diff --git a/tests/wpt/tests/webdriver/tests/bidi/script/evaluate/result_node.py b/tests/wpt/tests/webdriver/tests/bidi/script/evaluate/result_node.py
index a3ca316d027..a0bfd0d4c02 100644
--- a/tests/wpt/tests/webdriver/tests/bidi/script/evaluate/result_node.py
+++ b/tests/wpt/tests/webdriver/tests/bidi/script/evaluate/result_node.py
@@ -494,34 +494,141 @@ async def test_document_fragment_node(
@pytest.mark.asyncio
-async def test_node_within_object(bidi_session, get_test_page, top_context):
+@pytest.mark.parametrize(
+ "expression, expected",
+ [
+ (
+ """
+ [document.querySelector("img")]
+ """,
+ {
+ "type": "array",
+ "value": [
+ {
+ "type": "node",
+ "sharedId": any_string,
+ "value": {
+ "attributes": {},
+ "childNodeCount": 0,
+ "localName": "img",
+ "namespaceURI": "http://www.w3.org/1999/xhtml",
+ "nodeType": 1,
+ },
+ },
+ ],
+ },
+ ),
+ (
+ """
+ const map = new Map();
+ map.set(document.querySelector("img"), "elem");
+ map
+ """,
+ {
+ "type": "map",
+ "value": [[
+ {
+ "type": "node",
+ "sharedId": any_string,
+ "value": {
+ "attributes": {},
+ "childNodeCount": 0,
+ "localName": "img",
+ "namespaceURI": "http://www.w3.org/1999/xhtml",
+ "nodeType": 1
+ }
+ },
+ {
+ "type": "string",
+ "value": "elem"
+ }
+ ]]
+ }
+ ),
+ (
+ """
+ const map = new Map();
+ map.set("elem", document.querySelector("img"));
+ map
+ """,
+ {
+ "type": "map",
+ "value": [[
+ "elem", {
+ "type": "node",
+ "sharedId": any_string,
+ "value": {
+ "attributes": {},
+ "childNodeCount": 0,
+ "localName": "img",
+ "namespaceURI": "http://www.w3.org/1999/xhtml",
+ "nodeType": 1
+ }
+ }
+ ]]
+ }
+ ),
+ (
+ """
+ ({"elem": document.querySelector("img")})
+ """,
+ {
+ "type": "object",
+ "value": [
+ ["elem", {
+ "type": "node",
+ "sharedId": any_string,
+ "value": {
+ "attributes": {},
+ "childNodeCount": 0,
+ "localName": "img",
+ "namespaceURI": "http://www.w3.org/1999/xhtml",
+ "nodeType": 1
+ }
+ }]
+ ]
+ }
+ ),
+ (
+ """
+ const set = new Set();
+ set.add(document.querySelector("img"));
+ set
+ """,
+ {
+ "type": "set",
+ "value": [
+ {
+ "type": "node",
+ "sharedId": any_string,
+ "value": {
+ "attributes": {},
+ "childNodeCount": 0,
+ "localName": "img",
+ "namespaceURI": "http://www.w3.org/1999/xhtml",
+ "nodeType": 1,
+ },
+ },
+ ],
+ },
+ ),
+ ], ids=[
+ "array", "map-key", "map-value", "object", "set"
+ ]
+)
+async def test_node_embedded_within(
+ bidi_session, get_test_page, top_context, expression, expected
+):
await bidi_session.browsing_context.navigate(
context=top_context['context'], url=get_test_page(), wait="complete"
)
result = await bidi_session.script.evaluate(
- expression="""({"elem": document.querySelector("img")})""",
+ expression=expression,
target=ContextTarget(top_context["context"]),
await_promise=False,
)
- expected = {
- "type": "object",
- "value": [
- ["elem", {
- "type": "node",
- "sharedId": any_string,
- "value": {
- "attributes": {},
- "childNodeCount": 0,
- "localName": "img",
- "namespaceURI": "http://www.w3.org/1999/xhtml",
- "nodeType": 1
- }
- }]
- ]
- }
-
recursive_compare(expected, result)
diff --git a/tests/wpt/tests/webdriver/tests/classic/element_clear/clear.py b/tests/wpt/tests/webdriver/tests/classic/element_clear/clear.py
index 9b0d7f2133f..22c07b6a8ce 100644
--- a/tests/wpt/tests/webdriver/tests/classic/element_clear/clear.py
+++ b/tests/wpt/tests/webdriver/tests/classic/element_clear/clear.py
@@ -1,7 +1,7 @@
# META: timeout=long
import pytest
-from webdriver import Element
+from webdriver import WebElement
from tests.support.asserts import (
assert_element_has_focus,
@@ -45,7 +45,7 @@ def test_null_response_value(session, inline):
def test_no_top_browsing_context(session, closed_window):
- element = Element(session, "foo")
+ element = WebElement(session, "foo")
response = element_clear(session, element)
assert_error(response, "no such window")
@@ -59,14 +59,14 @@ def test_no_top_browsing_context(session, closed_window):
def test_no_browsing_context(session, closed_frame):
- element = Element(session, "foo")
+ element = WebElement(session, "foo")
response = element_clear(session, element)
assert_error(response, "no such window")
def test_no_such_element_with_invalid_value(session):
- element = Element(session, "foo")
+ element = WebElement(session, "foo")
response = element_clear(session, element)
assert_error(response, "no such element")
diff --git a/tests/wpt/tests/webdriver/tests/classic/element_click/click.py b/tests/wpt/tests/webdriver/tests/classic/element_click/click.py
index 3c3f7d70e6c..61acc923e8e 100644
--- a/tests/wpt/tests/webdriver/tests/classic/element_click/click.py
+++ b/tests/wpt/tests/webdriver/tests/classic/element_click/click.py
@@ -1,5 +1,5 @@
import pytest
-from webdriver import Element
+from webdriver import WebElement
from tests.support.asserts import assert_error, assert_success
@@ -21,7 +21,7 @@ def test_null_response_value(session, inline):
def test_no_top_browsing_context(session, closed_window):
- element = Element(session, "foo")
+ element = WebElement(session, "foo")
response = element_click(session, element)
assert_error(response, "no such window")
@@ -35,14 +35,14 @@ def test_no_top_browsing_context(session, closed_window):
def test_no_browsing_context(session, closed_frame):
- element = Element(session, "foo")
+ element = WebElement(session, "foo")
response = element_click(session, element)
assert_error(response, "no such window")
def test_no_such_element_with_invalid_value(session):
- element = Element(session, "foo")
+ element = WebElement(session, "foo")
response = element_click(session, element)
assert_error(response, "no such element")
diff --git a/tests/wpt/tests/webdriver/tests/classic/element_click/events.py b/tests/wpt/tests/webdriver/tests/classic/element_click/events.py
index 30f2dfa0a4a..5e80b52e879 100644
--- a/tests/wpt/tests/webdriver/tests/classic/element_click/events.py
+++ b/tests/wpt/tests/webdriver/tests/classic/element_click/events.py
@@ -1,4 +1,4 @@
-from webdriver import Element
+from webdriver import WebElement
from tests.support.asserts import assert_success
from tests.support.helpers import filter_dict
diff --git a/tests/wpt/tests/webdriver/tests/classic/element_send_keys/send_keys.py b/tests/wpt/tests/webdriver/tests/classic/element_send_keys/send_keys.py
index 281c7ad719d..92002f29457 100644
--- a/tests/wpt/tests/webdriver/tests/classic/element_send_keys/send_keys.py
+++ b/tests/wpt/tests/webdriver/tests/classic/element_send_keys/send_keys.py
@@ -1,6 +1,6 @@
import pytest
-from webdriver import Element
+from webdriver import WebElement
from webdriver.transport import Response
from tests.support.asserts import assert_error, assert_success
@@ -34,7 +34,7 @@ def test_null_response_value(session, inline):
def test_no_top_browsing_context(session, closed_window):
- element = Element(session, "foo")
+ element = WebElement(session, "foo")
response = element_send_keys(session, element, "foo")
assert_error(response, "no such window")
@@ -48,14 +48,14 @@ def test_no_top_browsing_context(session, closed_window):
def test_no_browsing_context(session, closed_frame):
- element = Element(session, "foo")
+ element = WebElement(session, "foo")
response = element_send_keys(session, element, "foo")
assert_error(response, "no such window")
def test_no_such_element_with_invalid_value(session):
- element = Element(session, "foo")
+ element = WebElement(session, "foo")
response = element_send_keys(session, element, "foo")
assert_error(response, "no such element")
diff --git a/tests/wpt/tests/webdriver/tests/classic/execute_async_script/arguments.py b/tests/wpt/tests/webdriver/tests/classic/execute_async_script/arguments.py
index ead6e0c186e..81b30de2678 100644
--- a/tests/wpt/tests/webdriver/tests/classic/execute_async_script/arguments.py
+++ b/tests/wpt/tests/webdriver/tests/classic/execute_async_script/arguments.py
@@ -1,6 +1,6 @@
import pytest
-from webdriver.client import Element, Frame, ShadowRoot, Window
+from webdriver.client import ShadowRoot, WebElement, WebFrame, WebWindow
from tests.support.asserts import assert_error, assert_success
from . import execute_async_script
@@ -54,8 +54,8 @@ def test_object(session):
assert actual[1] == value
-def test_no_such_element_with_invalid_value(session):
- element = Element(session, "foo")
+def test_no_such_element_with_unknown_id(session):
+ element = WebElement(session, "foo")
result = execute_async_script(session, """
arguments[1](true);
@@ -101,7 +101,7 @@ def test_no_such_element_from_other_frame(session, get_test_page, closed):
assert_error(result, "no such element")
-def test_no_such_shadow_root_with_unknown_shadow_root(session):
+def test_no_such_shadow_root_with_unknown_id(session):
shadow_root = ShadowRoot(session, "foo")
result = execute_async_script(session, """
@@ -159,18 +159,47 @@ def test_stale_element_reference(session, stale_element, as_frame):
assert_error(result, "stale element reference")
-@pytest.mark.parametrize("expression, expected_type, expected_class", [
- ("window.frames[0]", Frame, "Frame"),
- ("document.querySelector('div')", Element, "HTMLDivElement"),
- ("document.querySelector('custom-element').shadowRoot", ShadowRoot, "ShadowRoot"),
- ("window", Window, "Window")
+@pytest.mark.parametrize("type", [WebFrame, WebWindow], ids=["frame", "window"])
+@pytest.mark.parametrize("value", [None, False, 42, [], {}])
+def test_invalid_argument_for_window_with_invalid_type(session, type, value):
+ reference = type(session, value)
+
+ result = execute_async_script(session, "arguments[1](true)", args=(reference,))
+ assert_error(result, "invalid argument")
+
+
+def test_no_such_window_for_window_with_invalid_value(session, get_test_page):
+ session.url = get_test_page()
+
+ result = execute_async_script(session, "arguments[0]([window, window.frames[0]]);")
+ [window, frame] = assert_success(result)
+
+ assert isinstance(window, WebWindow)
+ assert isinstance(frame, WebFrame)
+
+ window_reference = WebWindow(session, frame.id)
+ frame_reference = WebFrame(session, window.id)
+
+ for reference in [window_reference, frame_reference]:
+ result = execute_async_script(session, "arguments[1](true)", args=(reference,))
+ assert_error(result, "no such window")
+
+
+@pytest.mark.parametrize("expression, expected_type", [
+ ("window.frames[0]", WebFrame),
+ ("document.querySelector('div')", WebElement),
+ ("document.querySelector('custom-element').shadowRoot", ShadowRoot),
+ ("window", WebWindow)
], ids=["frame", "node", "shadow-root", "window"])
-def test_element_reference(session, get_test_page, expression, expected_type, expected_class):
+def test_element_reference(session, get_test_page, expression, expected_type):
session.url = get_test_page(as_frame=False)
result = execute_async_script(session, f"arguments[0]({expression})")
reference = assert_success(result)
assert isinstance(reference, expected_type)
- result = execute_async_script(session, "arguments[1](arguments[0].constructor.name)", [reference])
- assert_success(result, expected_class)
+ result = execute_async_script(session, f"""
+ let resolve = arguments[1];
+ resolve(arguments[0] == {expression})
+ """, [reference])
+ assert_success(result, True)
diff --git a/tests/wpt/tests/webdriver/tests/classic/execute_async_script/execute_async.py b/tests/wpt/tests/webdriver/tests/classic/execute_async_script/execute_async.py
index 42cf4aacee8..3c8cc6210d4 100644
--- a/tests/wpt/tests/webdriver/tests/classic/execute_async_script/execute_async.py
+++ b/tests/wpt/tests/webdriver/tests/classic/execute_async_script/execute_async.py
@@ -1,6 +1,6 @@
import pytest
-from webdriver import Element
+from webdriver import WebElement
from webdriver.error import NoSuchAlertException
from webdriver.transport import Response
@@ -16,12 +16,12 @@ def test_null_parameter_value(session, http):
def test_no_top_browsing_context(session, closed_window):
- response = execute_async_script(session, "argument[0](1);")
+ response = execute_async_script(session, "arguments[0](1);")
assert_error(response, "no such window")
def test_no_browsing_context(session, closed_frame):
- response = execute_async_script(session, "argument[0](1);")
+ response = execute_async_script(session, "arguments[0](1);")
assert_error(response, "no such window")
diff --git a/tests/wpt/tests/webdriver/tests/classic/execute_async_script/node.py b/tests/wpt/tests/webdriver/tests/classic/execute_async_script/node.py
index 53abda4b300..2f1bf75e83c 100644
--- a/tests/wpt/tests/webdriver/tests/classic/execute_async_script/node.py
+++ b/tests/wpt/tests/webdriver/tests/classic/execute_async_script/node.py
@@ -1,6 +1,6 @@
import pytest
-from webdriver.client import Element, Frame, ShadowRoot, Window
+from webdriver.client import ShadowRoot, WebElement
from tests.support.asserts import assert_error, assert_success
from . import execute_async_script
@@ -59,11 +59,9 @@ def test_stale_element(session, get_test_page, as_frame):
@pytest.mark.parametrize("expression, expected_type", [
- ("window.frames[0]", Frame),
- ("document.querySelector('div')", Element),
+ ("document.querySelector('div')", WebElement),
("document.querySelector('custom-element').shadowRoot", ShadowRoot),
- ("window", Window),
-], ids=["frame", "node", "shadow-root", "window"])
+], ids=["element", "shadow-root"])
def test_element_reference(session, get_test_page, expression, expected_type):
session.url = get_test_page()
@@ -81,7 +79,7 @@ def test_element_reference(session, get_test_page, expression, expected_type):
(""" document"""),
(""" document.doctype"""),
], ids=["attribute", "text", "cdata", "processing_instruction", "comment", "document", "doctype"])
-def test_non_element_nodes(session, inline, expression):
+def test_not_supported_nodes(session, inline, expression):
session.url = inline(PAGE_DATA)
result = execute_async_script(session, f"arguments[0]({expression})")
diff --git a/tests/wpt/tests/webdriver/tests/classic/execute_async_script/window.py b/tests/wpt/tests/webdriver/tests/classic/execute_async_script/window.py
new file mode 100644
index 00000000000..f79bfdf49d9
--- /dev/null
+++ b/tests/wpt/tests/webdriver/tests/classic/execute_async_script/window.py
@@ -0,0 +1,33 @@
+import pytest
+
+from webdriver.client import WebFrame, WebWindow
+
+from tests.support.asserts import assert_success
+from . import execute_async_script
+
+
+@pytest.mark.parametrize("expression, expected_type", [
+ ("window.frames[0]", WebFrame),
+ ("window", WebWindow),
+], ids=["frame", "window"])
+def test_web_reference(session, get_test_page, expression, expected_type):
+ session.url = get_test_page()
+
+ result = execute_async_script(session, f"arguments[0]({expression})")
+ reference = assert_success(result)
+
+ assert isinstance(reference, expected_type)
+
+ if isinstance(reference, WebWindow):
+ assert reference.id in session.handles
+ else:
+ assert reference.id not in session.handles
+
+
+def test_window_open(session):
+ result = execute_async_script(
+ session, "window.foo = window.open(); arguments[0](window.foo);")
+ reference = assert_success(result)
+
+ assert isinstance(reference, WebWindow)
+ assert reference.id in session.handles
diff --git a/tests/wpt/tests/webdriver/tests/classic/execute_script/arguments.py b/tests/wpt/tests/webdriver/tests/classic/execute_script/arguments.py
index b8657ce0efa..ab5c5234ba1 100644
--- a/tests/wpt/tests/webdriver/tests/classic/execute_script/arguments.py
+++ b/tests/wpt/tests/webdriver/tests/classic/execute_script/arguments.py
@@ -1,6 +1,6 @@
import pytest
-from webdriver.client import Element, Frame, ShadowRoot, Window
+from webdriver.client import ShadowRoot, WebElement, WebFrame, WebWindow
from tests.support.asserts import assert_error, assert_success
from . import execute_script
@@ -46,8 +46,8 @@ def test_object(session):
assert actual[1] == value
-def test_no_such_element_with_invalid_value(session):
- element = Element(session, "foo")
+def test_no_such_element_with_unknown_id(session):
+ element = WebElement(session, "foo")
result = execute_script(session, "return true;", args=[element])
assert_error(result, "no such element")
@@ -87,7 +87,7 @@ def test_no_such_element_from_other_frame(session, get_test_page, closed):
assert_error(result, "no such element")
-def test_no_such_shadow_root_with_unknown_shadow_root(session):
+def test_no_such_shadow_root_with_unknown_id(session):
shadow_root = ShadowRoot(session, "foo")
result = execute_script(session, "return true;", args=[shadow_root])
@@ -147,18 +147,44 @@ def test_stale_element_reference(session, stale_element, as_frame):
assert_error(result, "stale element reference")
-@pytest.mark.parametrize("expression, expected_type, expected_class", [
- ("window.frames[0]", Frame, "Frame"),
- ("document.querySelector('div')", Element, "HTMLDivElement"),
- ("document.querySelector('custom-element').shadowRoot", ShadowRoot, "ShadowRoot"),
- ("window", Window, "Window")
+@pytest.mark.parametrize("type", [WebFrame, WebWindow], ids=["frame", "window"])
+@pytest.mark.parametrize("value", [None, False, 42, [], {}])
+def test_invalid_argument_for_window_with_invalid_type(session, type, value):
+ reference = type(session, value)
+
+ result = execute_script(session, "return true", args=(reference,))
+ assert_error(result, "invalid argument")
+
+
+def test_no_such_window_for_window_with_invalid_value(session, get_test_page):
+ session.url = get_test_page()
+
+ result = execute_script(session, "return [window, window.frames[0]];")
+ [window, frame] = assert_success(result)
+
+ assert isinstance(window, WebWindow)
+ assert isinstance(frame, WebFrame)
+
+ window_reference = WebWindow(session, frame.id)
+ frame_reference = WebFrame(session, window.id)
+
+ for reference in [window_reference, frame_reference]:
+ result = execute_script(session, "return true", args=(reference,))
+ assert_error(result, "no such window")
+
+
+@pytest.mark.parametrize("expression, expected_type", [
+ ("window.frames[0]", WebFrame),
+ ("document.querySelector('div')", WebElement),
+ ("document.querySelector('custom-element').shadowRoot", ShadowRoot),
+ ("window", WebWindow)
], ids=["frame", "node", "shadow-root", "window"])
-def test_element_reference(session, get_test_page, expression, expected_type, expected_class):
+def test_element_reference(session, get_test_page, expression, expected_type):
session.url = get_test_page(as_frame=False)
result = execute_script(session, f"return {expression}")
reference = assert_success(result)
assert isinstance(reference, expected_type)
- result = execute_script(session, "return arguments[0].constructor.name", [reference])
- assert_success(result, expected_class)
+ result = execute_script(session, f"return arguments[0] == {expression}", [reference])
+ assert_success(result, True)
diff --git a/tests/wpt/tests/webdriver/tests/classic/execute_script/execute.py b/tests/wpt/tests/webdriver/tests/classic/execute_script/execute.py
index fbccc986338..15ac1d0132a 100644
--- a/tests/wpt/tests/webdriver/tests/classic/execute_script/execute.py
+++ b/tests/wpt/tests/webdriver/tests/classic/execute_script/execute.py
@@ -1,6 +1,6 @@
import pytest
-from webdriver import Element
+from webdriver import WebElement
from webdriver.error import NoSuchAlertException
from webdriver.transport import Response
diff --git a/tests/wpt/tests/webdriver/tests/classic/execute_script/json_serialize_windowproxy.py b/tests/wpt/tests/webdriver/tests/classic/execute_script/json_serialize_windowproxy.py
deleted file mode 100644
index 8e76feda238..00000000000
--- a/tests/wpt/tests/webdriver/tests/classic/execute_script/json_serialize_windowproxy.py
+++ /dev/null
@@ -1,51 +0,0 @@
-import json
-
-from tests.support.asserts import assert_success
-from . import execute_script
-
-_window_id = "window-fcc6-11e5-b4f8-330a88ab9d7f"
-_frame_id = "frame-075b-4da1-b6ba-e579c2d3230a"
-
-
-def test_initial_window(session):
- # non-auxiliary top-level browsing context
- response = execute_script(session, "return window;")
- raw_json = assert_success(response)
-
- obj = json.loads(raw_json)
- assert len(obj) == 1
- assert _window_id in obj
- handle = obj[_window_id]
- assert handle in session.window_handles
-
-
-def test_window_open(session):
- # auxiliary browsing context
- session.execute_script("window.foo = window.open()")
-
- response = execute_script(session, "return window.foo;")
- raw_json = assert_success(response)
-
- obj = json.loads(raw_json)
- assert len(obj) == 1
- assert _window_id in obj
- handle = obj[_window_id]
- assert handle in session.window_handles
-
-
-def test_frame(session):
- # nested browsing context
- append = """
- window.frame = document.createElement('iframe');
- document.body.appendChild(frame);
- """
- session.execute_script(append)
-
- response = execute_script(session, "return frame.contentWindow;")
- raw_json = assert_success(response)
-
- obj = json.loads(raw_json)
- assert len(obj) == 1
- assert _frame_id in obj
- handle = obj[_frame_id]
- assert handle not in session.window_handles
diff --git a/tests/wpt/tests/webdriver/tests/classic/execute_script/node.py b/tests/wpt/tests/webdriver/tests/classic/execute_script/node.py
index caf85988f15..61cf3463dcb 100644
--- a/tests/wpt/tests/webdriver/tests/classic/execute_script/node.py
+++ b/tests/wpt/tests/webdriver/tests/classic/execute_script/node.py
@@ -1,6 +1,6 @@
import pytest
-from webdriver.client import Element, Frame, ShadowRoot, Window
+from webdriver.client import WebElement, ShadowRoot
from tests.support.asserts import assert_error, assert_success
from . import execute_script
@@ -58,12 +58,10 @@ def test_stale_element(session, get_test_page, as_frame):
@pytest.mark.parametrize("expression, expected_type", [
- ("window.frames[0]", Frame),
- ("document.querySelector('div')", Element),
+ ("document.querySelector('div')", WebElement),
("document.querySelector('custom-element').shadowRoot", ShadowRoot),
- ("window", Window),
-], ids=["frame", "node", "shadow-root", "window"])
-def test_element_reference(session, get_test_page, expression, expected_type):
+], ids=["element", "shadow-root"])
+def test_web_reference(session, get_test_page, expression, expected_type):
session.url = get_test_page()
result = execute_script(session, f"return {expression}")
@@ -80,7 +78,7 @@ def test_element_reference(session, get_test_page, expression, expected_type):
(""" document"""),
(""" document.doctype"""),
], ids=["attribute", "text", "cdata", "processing_instruction", "comment", "document", "doctype"])
-def test_non_element_nodes(session, inline, expression):
+def test_not_supported_nodes(session, inline, expression):
session.url = inline(PAGE_DATA)
result = execute_script(session, f"return {expression}")
diff --git a/tests/wpt/tests/webdriver/tests/classic/execute_script/window.py b/tests/wpt/tests/webdriver/tests/classic/execute_script/window.py
new file mode 100644
index 00000000000..9ab45d7cb78
--- /dev/null
+++ b/tests/wpt/tests/webdriver/tests/classic/execute_script/window.py
@@ -0,0 +1,87 @@
+import pytest
+
+from webdriver.client import WebFrame, WebWindow
+
+from tests.support.asserts import assert_success
+from . import execute_script
+
+
+@pytest.mark.parametrize("expression, expected_type", [
+ ("window.frames[0]", WebFrame),
+ ("window", WebWindow),
+], ids=["frame", "window"])
+def test_web_reference(session, get_test_page, expression, expected_type):
+ session.url = get_test_page()
+
+ result = execute_script(session, f"return {expression}")
+ reference = assert_success(result)
+
+ assert isinstance(reference, expected_type)
+
+ if isinstance(reference, WebWindow):
+ assert reference.id in session.handles
+ else:
+ assert reference.id not in session.handles
+
+
+@pytest.mark.parametrize("expression, expected_type", [
+ ("window.frames[0]", WebFrame),
+ ("window", WebWindow),
+], ids=["frame", "window"])
+def test_web_reference_in_array(session, get_test_page, expression, expected_type):
+ session.url = get_test_page()
+
+ result = execute_script(session, f"return [{expression}]")
+ value = assert_success(result)
+
+ assert isinstance(value[0], expected_type)
+
+ if isinstance(value[0], WebWindow):
+ assert value[0].id in session.handles
+ else:
+ assert value[0].id not in session.handles
+
+
+@pytest.mark.parametrize("expression, expected_type", [
+ ("window.frames[0]", WebFrame),
+ ("window", WebWindow),
+], ids=["frame", "window"])
+def test_web_reference_in_object(session, get_test_page, expression, expected_type):
+ session.url = get_test_page()
+
+ result = execute_script(session, f"""return {{"ref": {expression}}}""")
+ reference = assert_success(result)
+
+ assert isinstance(reference["ref"], expected_type)
+
+ if isinstance(reference["ref"], WebWindow):
+ assert reference["ref"].id in session.handles
+ else:
+ assert reference["ref"].id not in session.handles
+
+
+def test_window_open(session):
+ result = execute_script(session, "window.foo = window.open(); return window.foo;")
+ reference = assert_success(result)
+
+ assert isinstance(reference, WebWindow)
+ assert reference.id in session.handles
+
+
+def test_same_id_after_cross_origin_navigation(session, get_test_page):
+ params = {"pipe": "header(Cross-Origin-Opener-Policy,same-origin)"}
+
+ first_page = get_test_page(parameters=params, protocol="https")
+ second_page = get_test_page(parameters=params, protocol="https", domain="alt")
+
+ session.url = first_page
+
+ result = execute_script(session, "return window")
+ window_before = assert_success(result)
+
+ session.url = second_page
+
+ result = execute_script(session, "return window")
+ window_after = assert_success(result)
+
+ assert window_before == window_after
diff --git a/tests/wpt/tests/webdriver/tests/classic/find_element_from_shadow_root/find.py b/tests/wpt/tests/webdriver/tests/classic/find_element_from_shadow_root/find.py
index 3f1b64a61c5..c658152ee69 100644
--- a/tests/wpt/tests/webdriver/tests/classic/find_element_from_shadow_root/find.py
+++ b/tests/wpt/tests/webdriver/tests/classic/find_element_from_shadow_root/find.py
@@ -1,5 +1,5 @@
import pytest
-from webdriver.client import Element, ShadowRoot
+from webdriver.client import WebElement, ShadowRoot
from webdriver.transport import Response
from tests.support.asserts import assert_error, assert_same_element, assert_success
@@ -174,7 +174,7 @@ def test_find_element(session, get_test_page, using, value, mode):
result = find_element(session, shadow_root.id, using, value)
value = assert_success(result)
- element = Element.from_json(value, session)
+ element = WebElement.from_json(value, session)
assert element.text == expected_text
@@ -243,5 +243,5 @@ def test_find_element_in_nested_shadow_root(session, get_test_page, mode):
result = find_element(session, nested_shadow_root.id, "css selector", "#linkText")
value = assert_success(result)
- element = Element.from_json(value, session)
+ element = WebElement.from_json(value, session)
assert element.text == expected_text
diff --git a/tests/wpt/tests/webdriver/tests/classic/find_elements_from_shadow_root/find.py b/tests/wpt/tests/webdriver/tests/classic/find_elements_from_shadow_root/find.py
index ffdaa7e84b0..188fff29212 100644
--- a/tests/wpt/tests/webdriver/tests/classic/find_elements_from_shadow_root/find.py
+++ b/tests/wpt/tests/webdriver/tests/classic/find_elements_from_shadow_root/find.py
@@ -1,5 +1,5 @@
import pytest
-from webdriver.client import Element, ShadowRoot
+from webdriver.client import WebElement, ShadowRoot
from webdriver.transport import Response
from tests.support.asserts import assert_error, assert_same_element, assert_success
@@ -177,7 +177,7 @@ def test_find_elements(session, get_test_page, using, value, mode):
assert len(value) == 1
- element = Element.from_json(value[0], session)
+ element = WebElement.from_json(value[0], session)
assert element.text == expected_text
@@ -256,5 +256,5 @@ def test_find_elements_in_nested_shadow_root(
assert len(value) == 1
- element = Element.from_json(value[0], session)
+ element = WebElement.from_json(value[0], session)
assert element.text == expected_text
diff --git a/tests/wpt/tests/webdriver/tests/classic/get_computed_label/get.py b/tests/wpt/tests/webdriver/tests/classic/get_computed_label/get.py
index 0dc00a471a9..e023b79cea5 100644
--- a/tests/wpt/tests/webdriver/tests/classic/get_computed_label/get.py
+++ b/tests/wpt/tests/webdriver/tests/classic/get_computed_label/get.py
@@ -1,6 +1,6 @@
import pytest
-from webdriver import Element
+from webdriver import WebElement
from webdriver.error import NoSuchAlertException
from tests.support.asserts import assert_error, assert_success
@@ -19,7 +19,7 @@ def test_no_browsing_context(session, closed_frame):
def test_no_such_element_with_invalid_value(session):
- element = Element(session, "foo")
+ element = WebElement(session, "foo")
result = get_computed_label(session, element.id)
assert_error(result, "no such element")
diff --git a/tests/wpt/tests/webdriver/tests/classic/get_computed_role/get.py b/tests/wpt/tests/webdriver/tests/classic/get_computed_role/get.py
index 51b6a8b3b6d..1b8489675ce 100644
--- a/tests/wpt/tests/webdriver/tests/classic/get_computed_role/get.py
+++ b/tests/wpt/tests/webdriver/tests/classic/get_computed_role/get.py
@@ -1,6 +1,6 @@
import pytest
-from webdriver import Element
+from webdriver import WebElement
from webdriver.error import NoSuchAlertException
from tests.support.asserts import assert_error, assert_success
@@ -19,7 +19,7 @@ def test_no_browsing_context(session, closed_frame):
def test_no_such_element_with_invalid_value(session):
- element = Element(session, "foo")
+ element = WebElement(session, "foo")
result = get_computed_role(session, element.id)
assert_error(result, "no such element")
diff --git a/tests/wpt/tests/webdriver/tests/classic/get_element_attribute/get.py b/tests/wpt/tests/webdriver/tests/classic/get_element_attribute/get.py
index 375f25032c0..0fcfd00c97c 100644
--- a/tests/wpt/tests/webdriver/tests/classic/get_element_attribute/get.py
+++ b/tests/wpt/tests/webdriver/tests/classic/get_element_attribute/get.py
@@ -1,6 +1,6 @@
import pytest
-from webdriver import Element
+from webdriver import WebElement
from tests.support.asserts import assert_error, assert_success
@@ -30,7 +30,7 @@ def test_no_browsing_context(session, closed_frame):
def test_no_such_element_with_invalid_value(session):
- element = Element(session, "foo")
+ element = WebElement(session, "foo")
response = get_element_attribute(session, element.id, "id")
assert_error(response, "no such element")
diff --git a/tests/wpt/tests/webdriver/tests/classic/get_element_css_value/get.py b/tests/wpt/tests/webdriver/tests/classic/get_element_css_value/get.py
index 6f0a8a56395..1f6f571149b 100644
--- a/tests/wpt/tests/webdriver/tests/classic/get_element_css_value/get.py
+++ b/tests/wpt/tests/webdriver/tests/classic/get_element_css_value/get.py
@@ -1,6 +1,6 @@
import pytest
-from webdriver import Element
+from webdriver import WebElement
from tests.support.asserts import assert_error, assert_success
@@ -34,7 +34,7 @@ def test_no_browsing_context(session, closed_frame):
def test_no_such_element_with_invalid_value(session):
- element = Element(session, "foo")
+ element = WebElement(session, "foo")
response = get_element_css_value(session, element.id, "display")
assert_error(response, "no such element")
diff --git a/tests/wpt/tests/webdriver/tests/classic/get_element_property/get.py b/tests/wpt/tests/webdriver/tests/classic/get_element_property/get.py
index bb63481dfca..12d48a3abb5 100644
--- a/tests/wpt/tests/webdriver/tests/classic/get_element_property/get.py
+++ b/tests/wpt/tests/webdriver/tests/classic/get_element_property/get.py
@@ -1,6 +1,6 @@
import pytest
-from webdriver import Element, Frame, ShadowRoot, Window
+from webdriver import WebElement, WebFrame, ShadowRoot, WebWindow
from tests.support.asserts import assert_error, assert_same_element, assert_success
@@ -31,7 +31,7 @@ def test_no_browsing_context(session, closed_frame):
def test_no_such_element_with_invalid_value(session):
- element = Element(session, "foo")
+ element = WebElement(session, "foo")
response = get_element_property(session, element.id, "id")
assert_error(response, "no such element")
@@ -165,10 +165,10 @@ def test_primitives_set_by_execute_script(session, inline, js_primitive, py_prim
@pytest.mark.parametrize("js_web_reference,py_web_reference", [
- ("element", Element),
- ("frame", Frame),
+ ("element", WebElement),
+ ("frame", WebFrame),
("shadowRoot", ShadowRoot),
- ("window", Window),
+ ("window", WebWindow),
])
def test_web_reference(session, get_test_page, js_web_reference, py_web_reference):
session.url = get_test_page()
diff --git a/tests/wpt/tests/webdriver/tests/classic/get_element_rect/get.py b/tests/wpt/tests/webdriver/tests/classic/get_element_rect/get.py
index 942f119f43c..959ccc455ec 100644
--- a/tests/wpt/tests/webdriver/tests/classic/get_element_rect/get.py
+++ b/tests/wpt/tests/webdriver/tests/classic/get_element_rect/get.py
@@ -1,6 +1,6 @@
import pytest
-from webdriver import Element
+from webdriver import WebElement
from tests.support.asserts import assert_error, assert_success
from tests.support.helpers import element_rect
@@ -34,7 +34,7 @@ def test_no_browsing_context(session, closed_frame):
def test_no_such_element_with_invalid_value(session):
- element = Element(session, "foo")
+ element = WebElement(session, "foo")
response = get_element_rect(session, element.id)
assert_error(response, "no such element")
diff --git a/tests/wpt/tests/webdriver/tests/classic/get_element_shadow_root/get.py b/tests/wpt/tests/webdriver/tests/classic/get_element_shadow_root/get.py
index d9adde0b9e3..25e68c1bbac 100644
--- a/tests/wpt/tests/webdriver/tests/classic/get_element_shadow_root/get.py
+++ b/tests/wpt/tests/webdriver/tests/classic/get_element_shadow_root/get.py
@@ -1,6 +1,6 @@
import pytest
-from webdriver import Element
+from webdriver import WebElement
from tests.support.asserts import assert_error, assert_same_element, assert_success
@@ -30,7 +30,7 @@ def test_no_browsing_context(session, closed_frame):
def test_no_such_element_with_invalid_value(session):
- element = Element(session, "foo")
+ element = WebElement(session, "foo")
response = get_shadow_root(session, element.id)
assert_error(response, "no such element")
diff --git a/tests/wpt/tests/webdriver/tests/classic/get_element_tag_name/get.py b/tests/wpt/tests/webdriver/tests/classic/get_element_tag_name/get.py
index 3bb03d79886..d8bb3acc500 100644
--- a/tests/wpt/tests/webdriver/tests/classic/get_element_tag_name/get.py
+++ b/tests/wpt/tests/webdriver/tests/classic/get_element_tag_name/get.py
@@ -1,6 +1,6 @@
import pytest
-from webdriver import Element
+from webdriver import WebElement
from tests.support.asserts import assert_error, assert_success
@@ -30,7 +30,7 @@ def test_no_browsing_context(session, closed_frame):
def test_no_such_element_with_invalid_value(session):
- element = Element(session, "foo")
+ element = WebElement(session, "foo")
response = get_element_tag_name(session, element.id)
assert_error(response, "no such element")
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 e8d559cf661..2a2363c0528 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
@@ -1,6 +1,6 @@
import pytest
-from webdriver import Element
+from webdriver import WebElement
from tests.support.asserts import assert_error, assert_success
@@ -30,7 +30,7 @@ def test_no_browsing_context(session, closed_frame):
def test_no_such_element_with_invalid_value(session):
- element = Element(session, "foo")
+ element = WebElement(session, "foo")
response = get_element_text(session, element.id)
assert_error(response, "no such element")
diff --git a/tests/wpt/tests/webdriver/tests/classic/is_element_enabled/enabled.py b/tests/wpt/tests/webdriver/tests/classic/is_element_enabled/enabled.py
index fccff383a55..24fc85fdad2 100644
--- a/tests/wpt/tests/webdriver/tests/classic/is_element_enabled/enabled.py
+++ b/tests/wpt/tests/webdriver/tests/classic/is_element_enabled/enabled.py
@@ -1,6 +1,6 @@
import pytest
-from webdriver import Element
+from webdriver import WebElement
from tests.support.asserts import assert_error, assert_success
@@ -33,7 +33,7 @@ def test_no_browsing_context(session, closed_frame):
def test_no_such_element_with_invalid_value(session):
- element = Element(session, "foo")
+ element = WebElement(session, "foo")
response = is_element_enabled(session, element.id)
assert_error(response, "no such element")
diff --git a/tests/wpt/tests/webdriver/tests/classic/is_element_selected/selected.py b/tests/wpt/tests/webdriver/tests/classic/is_element_selected/selected.py
index 1fb5b9ce86b..bf650de3e23 100644
--- a/tests/wpt/tests/webdriver/tests/classic/is_element_selected/selected.py
+++ b/tests/wpt/tests/webdriver/tests/classic/is_element_selected/selected.py
@@ -1,6 +1,6 @@
import pytest
-from webdriver import Element
+from webdriver import WebElement
from tests.support.asserts import assert_error, assert_success
@@ -49,7 +49,7 @@ def test_no_browsing_context(session, closed_frame):
def test_no_such_element_with_invalid_value(session):
- element = Element(session, "foo")
+ element = WebElement(session, "foo")
response = is_element_selected(session, element.id)
assert_error(response, "no such element")
diff --git a/tests/wpt/tests/webdriver/tests/classic/perform_actions/pointer_mouse.py b/tests/wpt/tests/webdriver/tests/classic/perform_actions/pointer_mouse.py
index 97295f56f41..6ccb7c404e0 100644
--- a/tests/wpt/tests/webdriver/tests/classic/perform_actions/pointer_mouse.py
+++ b/tests/wpt/tests/webdriver/tests/classic/perform_actions/pointer_mouse.py
@@ -188,6 +188,24 @@ def test_click_navigation(session, url, inline):
Poll(session, message=error_message).until(lambda s: s.url == destination)
+@pytest.mark.parametrize("x, y, event_count", [
+ (0, 0, 0),
+ (1, 0, 1),
+ (0, 1, 1),
+], ids=["default value", "x", "y"])
+def test_move_to_position_in_viewport(
+ session, test_actions_page, mouse_chain, x, y, event_count
+):
+ mouse_chain.pointer_move(x, y).perform()
+ events = get_events(session)
+ assert len(events) == event_count
+
+ # Move again to check that no further mouse move event is emitted.
+ mouse_chain.pointer_move(x, y).perform()
+ events = get_events(session)
+ assert len(events) == event_count
+
+
@pytest.mark.parametrize("drag_duration", [0, 300, 800])
@pytest.mark.parametrize("dx, dy", [
(20, 0), (0, 15), (10, 15), (-20, 0), (10, -15), (-10, -15)
diff --git a/tests/wpt/tests/webdriver/tests/classic/take_element_screenshot/screenshot.py b/tests/wpt/tests/webdriver/tests/classic/take_element_screenshot/screenshot.py
index ea4cc290db4..fdc0d65b1d9 100644
--- a/tests/wpt/tests/webdriver/tests/classic/take_element_screenshot/screenshot.py
+++ b/tests/wpt/tests/webdriver/tests/classic/take_element_screenshot/screenshot.py
@@ -1,6 +1,6 @@
import pytest
-from webdriver import Element
+from webdriver import WebElement
from tests.support.asserts import assert_error, assert_success
from tests.support.image import png_dimensions
@@ -33,7 +33,7 @@ def test_no_browsing_context(session, closed_frame, inline):
def test_no_such_element_with_invalid_value(session):
- element = Element(session, "foo")
+ element = WebElement(session, "foo")
response = take_element_screenshot(session, element.id)
assert_error(response, "no such element")
diff --git a/tests/wpt/tests/webdriver/tests/support/asserts.py b/tests/wpt/tests/webdriver/tests/support/asserts.py
index 04bd1993316..9d31ff7b124 100644
--- a/tests/wpt/tests/webdriver/tests/support/asserts.py
+++ b/tests/wpt/tests/webdriver/tests/support/asserts.py
@@ -1,7 +1,7 @@
import imghdr
from base64 import decodebytes
-from webdriver import Element, NoSuchAlertException, WebDriverException
+from webdriver import NoSuchAlertException, WebDriverException, WebElement
# WebDriver specification ID: dfn-error-response-data
@@ -148,17 +148,17 @@ def assert_is_active_element(session, element):
def assert_same_element(session, a, b):
"""Verify that two element references describe the same element."""
if isinstance(a, dict):
- assert Element.identifier in a, "Actual value does not describe an element"
- a_id = a[Element.identifier]
- elif isinstance(a, Element):
+ assert WebElement.identifier in a, "Actual value does not describe an element"
+ a_id = a[WebElement.identifier]
+ elif isinstance(a, WebElement):
a_id = a.id
else:
raise AssertionError("Actual value is not a dictionary or web element")
if isinstance(b, dict):
- assert Element.identifier in b, "Expected value does not describe an element"
- b_id = b[Element.identifier]
- elif isinstance(b, Element):
+ assert WebElement.identifier in b, "Expected value does not describe an element"
+ b_id = b[WebElement.identifier]
+ elif isinstance(b, WebElement):
b_id = b.id
else:
raise AssertionError("Expected value is not a dictionary or web element")
diff --git a/tests/wpt/tests/webtransport/echo-large-bidirectional-streams.https.html b/tests/wpt/tests/webtransport/echo-large-bidirectional-streams.https.any.js
index daa7c1b9b36..3f46530327e 100644
--- a/tests/wpt/tests/webtransport/echo-large-bidirectional-streams.https.html
+++ b/tests/wpt/tests/webtransport/echo-large-bidirectional-streams.https.any.js
@@ -1,10 +1,7 @@
-<!DOCTYPE html>
-<meta charset="utf-8"/>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/common/get-host-info.sub.js"></script>
-<script src="resources/webtransport-test-helpers.sub.js"></script>
-<script>
+// META: global=window,worker
+// META: script=/common/get-host-info.sub.js
+// META: script=resources/webtransport-test-helpers.sub.js
+
// A test that aims to reproduce https://crbug.com/1369030 -- note that since
// the bug in question is a race condition, this test will probably be flaky if
// this is actually broken.
@@ -23,5 +20,3 @@ promise_test(async t => {
assert_equals(response.byteLength, numBytes);
}
}, 'Ensure large bidirectional streams does not cause race condition');
-
-</script>
diff --git a/tests/wpt/tests/xhr/resources/auth1/auth.py b/tests/wpt/tests/xhr/resources/auth1/auth.py
index db4f7bc4c9f..3797aaa52e9 100644
--- a/tests/wpt/tests/xhr/resources/auth1/auth.py
+++ b/tests/wpt/tests/xhr/resources/auth1/auth.py
@@ -1,12 +1,13 @@
-import imp
import os
from wptserve.utils import isomorphic_decode
+from tools.wpt.utils import load_source
+
here = os.path.dirname(os.path.abspath(isomorphic_decode(__file__)))
def main(request, response):
- auth = imp.load_source(u"", os.path.join(here,
+ auth = load_source(u"", os.path.join(here,
u"..",
u"authentication.py"))
return auth.main(request, response)
diff --git a/tests/wpt/tests/xhr/resources/auth10/auth.py b/tests/wpt/tests/xhr/resources/auth10/auth.py
index db4f7bc4c9f..568d31e9068 100644
--- a/tests/wpt/tests/xhr/resources/auth10/auth.py
+++ b/tests/wpt/tests/xhr/resources/auth10/auth.py
@@ -1,12 +1,14 @@
-import imp
import os
from wptserve.utils import isomorphic_decode
+from tools.wpt.utils import load_source
+
here = os.path.dirname(os.path.abspath(isomorphic_decode(__file__)))
+
def main(request, response):
- auth = imp.load_source(u"", os.path.join(here,
+ auth = load_source(u"", os.path.join(here,
u"..",
u"authentication.py"))
return auth.main(request, response)
diff --git a/tests/wpt/tests/xhr/resources/auth11/auth.py b/tests/wpt/tests/xhr/resources/auth11/auth.py
index db4f7bc4c9f..3797aaa52e9 100644
--- a/tests/wpt/tests/xhr/resources/auth11/auth.py
+++ b/tests/wpt/tests/xhr/resources/auth11/auth.py
@@ -1,12 +1,13 @@
-import imp
import os
from wptserve.utils import isomorphic_decode
+from tools.wpt.utils import load_source
+
here = os.path.dirname(os.path.abspath(isomorphic_decode(__file__)))
def main(request, response):
- auth = imp.load_source(u"", os.path.join(here,
+ auth = load_source(u"", os.path.join(here,
u"..",
u"authentication.py"))
return auth.main(request, response)
diff --git a/tests/wpt/tests/xhr/resources/auth2/auth.py b/tests/wpt/tests/xhr/resources/auth2/auth.py
index db4f7bc4c9f..568d31e9068 100644
--- a/tests/wpt/tests/xhr/resources/auth2/auth.py
+++ b/tests/wpt/tests/xhr/resources/auth2/auth.py
@@ -1,12 +1,14 @@
-import imp
import os
from wptserve.utils import isomorphic_decode
+from tools.wpt.utils import load_source
+
here = os.path.dirname(os.path.abspath(isomorphic_decode(__file__)))
+
def main(request, response):
- auth = imp.load_source(u"", os.path.join(here,
+ auth = load_source(u"", os.path.join(here,
u"..",
u"authentication.py"))
return auth.main(request, response)
diff --git a/tests/wpt/tests/xhr/resources/auth2/corsenabled.py b/tests/wpt/tests/xhr/resources/auth2/corsenabled.py
index bec6687dbe9..7b9d3b65aba 100644
--- a/tests/wpt/tests/xhr/resources/auth2/corsenabled.py
+++ b/tests/wpt/tests/xhr/resources/auth2/corsenabled.py
@@ -1,8 +1,9 @@
-import imp
import os
from wptserve.utils import isomorphic_decode
+from tools.wpt.utils import load_source
+
here = os.path.dirname(isomorphic_decode(__file__))
def main(request, response):
@@ -11,7 +12,7 @@ def main(request, response):
response.headers.set(b'Access-Control-Allow-Methods', b'GET')
response.headers.set(b'Access-Control-Allow-Headers', b'authorization, x-user, x-pass')
response.headers.set(b'Access-Control-Expose-Headers', b'x-challenge, xhr-user, ses-user')
- auth = imp.load_source(u"", os.path.abspath(os.path.join(here, os.pardir, u"authentication.py")))
+ auth = load_source(u"", os.path.abspath(os.path.join(here, os.pardir, u"authentication.py")))
if request.method == u"OPTIONS":
return b""
else:
diff --git a/tests/wpt/tests/xhr/resources/auth3/auth.py b/tests/wpt/tests/xhr/resources/auth3/auth.py
index db4f7bc4c9f..3797aaa52e9 100644
--- a/tests/wpt/tests/xhr/resources/auth3/auth.py
+++ b/tests/wpt/tests/xhr/resources/auth3/auth.py
@@ -1,12 +1,13 @@
-import imp
import os
from wptserve.utils import isomorphic_decode
+from tools.wpt.utils import load_source
+
here = os.path.dirname(os.path.abspath(isomorphic_decode(__file__)))
def main(request, response):
- auth = imp.load_source(u"", os.path.join(here,
+ auth = load_source(u"", os.path.join(here,
u"..",
u"authentication.py"))
return auth.main(request, response)
diff --git a/tests/wpt/tests/xhr/resources/auth4/auth.py b/tests/wpt/tests/xhr/resources/auth4/auth.py
index db4f7bc4c9f..3797aaa52e9 100644
--- a/tests/wpt/tests/xhr/resources/auth4/auth.py
+++ b/tests/wpt/tests/xhr/resources/auth4/auth.py
@@ -1,12 +1,13 @@
-import imp
import os
from wptserve.utils import isomorphic_decode
+from tools.wpt.utils import load_source
+
here = os.path.dirname(os.path.abspath(isomorphic_decode(__file__)))
def main(request, response):
- auth = imp.load_source(u"", os.path.join(here,
+ auth = load_source(u"", os.path.join(here,
u"..",
u"authentication.py"))
return auth.main(request, response)
diff --git a/tests/wpt/tests/xhr/resources/auth7/corsenabled.py b/tests/wpt/tests/xhr/resources/auth7/corsenabled.py
index 7a060627b70..c82ba4e6bc4 100644
--- a/tests/wpt/tests/xhr/resources/auth7/corsenabled.py
+++ b/tests/wpt/tests/xhr/resources/auth7/corsenabled.py
@@ -1,8 +1,9 @@
-import imp
import os
from wptserve.utils import isomorphic_decode
+from tools.wpt.utils import load_source
+
here = os.path.dirname(isomorphic_decode(__file__))
def main(request, response):
@@ -11,7 +12,7 @@ def main(request, response):
response.headers.set(b'Access-Control-Allow-Methods', b'GET')
response.headers.set(b'Access-Control-Allow-Headers', b'authorization, x-user, x-pass')
response.headers.set(b'Access-Control-Expose-Headers', b'x-challenge, xhr-user, ses-user')
- auth = imp.load_source(u"", os.path.join(here,
+ auth = load_source(u"", os.path.join(here,
os.pardir,
u"authentication.py"))
if request.method == u"OPTIONS":
diff --git a/tests/wpt/tests/xhr/resources/auth8/corsenabled-no-authorize.py b/tests/wpt/tests/xhr/resources/auth8/corsenabled-no-authorize.py
index af8e7c4c170..4fdf99e2658 100644
--- a/tests/wpt/tests/xhr/resources/auth8/corsenabled-no-authorize.py
+++ b/tests/wpt/tests/xhr/resources/auth8/corsenabled-no-authorize.py
@@ -1,8 +1,9 @@
-import imp
import os
from wptserve.utils import isomorphic_decode
+from tools.wpt.utils import load_source
+
here = os.path.dirname(isomorphic_decode(__file__))
def main(request, response):
@@ -11,7 +12,7 @@ def main(request, response):
response.headers.set(b'Access-Control-Allow-Methods', b'GET')
response.headers.set(b'Access-Control-Allow-Headers', b'x-user, x-pass')
response.headers.set(b'Access-Control-Expose-Headers', b'x-challenge, xhr-user, ses-user')
- auth = imp.load_source(u"", os.path.join(here,
+ auth = load_source(u"", os.path.join(here,
os.pardir,
u"authentication.py"))
if request.method == u"OPTIONS":
diff --git a/tests/wpt/tests/xhr/resources/auth9/auth.py b/tests/wpt/tests/xhr/resources/auth9/auth.py
index db4f7bc4c9f..3797aaa52e9 100644
--- a/tests/wpt/tests/xhr/resources/auth9/auth.py
+++ b/tests/wpt/tests/xhr/resources/auth9/auth.py
@@ -1,12 +1,13 @@
-import imp
import os
from wptserve.utils import isomorphic_decode
+from tools.wpt.utils import load_source
+
here = os.path.dirname(os.path.abspath(isomorphic_decode(__file__)))
def main(request, response):
- auth = imp.load_source(u"", os.path.join(here,
+ auth = load_source(u"", os.path.join(here,
u"..",
u"authentication.py"))
return auth.main(request, response)