aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2016-04-21 16:53:18 +0530
committerbors-servo <lbergstrom+bors@mozilla.com>2016-04-21 16:53:18 +0530
commit1eec5d9f7222dd3f7020b51e18ed6df3386b18f9 (patch)
treefc7ece0869b272c92aa036a9852eedc41bdd56cf /tests
parent7e370c4df4ee0c564322a0bebd34b31359e88d85 (diff)
parentabcd4b654fd7a7adf493617bf6fe3b9ace15f6bb (diff)
downloadservo-1eec5d9f7222dd3f7020b51e18ed6df3386b18f9.tar.gz
servo-1eec5d9f7222dd3f7020b51e18ed6df3386b18f9.zip
Auto merge of #10777 - servo:wpt-20160421, r=Ms2ger
Update web-platform-tests to revision 0a518aaff73532a26e175789f7e75fa99593ac64 <!-- Reviewable:start --> This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/10777) <!-- Reviewable:end -->
Diffstat (limited to 'tests')
-rw-r--r--tests/wpt/metadata/DOMEvents/tests/approved/EventObject.after.dispatchEvent.html.ini5
-rw-r--r--tests/wpt/metadata/DOMEvents/tests/submissions/Microsoft/converted/EventObject.after.dispatchEvent.html.ini5
-rw-r--r--tests/wpt/metadata/FileAPI/blob/Blob-constructor.html.ini7
-rw-r--r--tests/wpt/metadata/MANIFEST.json201
-rw-r--r--tests/wpt/metadata/cssom-view/elementScroll.html.ini1
-rw-r--r--tests/wpt/metadata/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-1.html.ini6
-rw-r--r--tests/wpt/metadata/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-2.html.ini6
-rw-r--r--tests/wpt/metadata/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-3.html.ini6
-rw-r--r--tests/wpt/metadata/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-4.html.ini6
-rw-r--r--tests/wpt/metadata/mozilla-sync2
-rw-r--r--tests/wpt/metadata/websockets/constructor/018.html.ini5
-rw-r--r--tests/wpt/mozilla/meta/MANIFEST.json1
-rw-r--r--tests/wpt/web-platform-tests/DOMEvents/tests/approved/EventObject.after.dispatchEvent.html44
-rw-r--r--tests/wpt/web-platform-tests/DOMEvents/tests/submissions/Microsoft/converted/EventObject.after.dispatchEvent.html45
-rw-r--r--tests/wpt/web-platform-tests/FileAPI/blob/Blob-constructor.html14
-rw-r--r--tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-002-ref.html25
-rw-r--r--tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-002.html29
-rw-r--r--tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-003-ref.html28
-rw-r--r--tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-003.html35
-rw-r--r--tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-004-ref.html34
-rw-r--r--tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-004.html38
-rw-r--r--tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-005-ref.html13
-rw-r--r--tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-005.html17
-rw-r--r--tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-006-ref.html24
-rw-r--r--tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-006.html28
-rw-r--r--tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/form-action-src-allowed.sub.html2
-rw-r--r--tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/form-action-src-blocked.sub.html2
-rw-r--r--tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/form-action-src-get-allowed.sub.html3
-rw-r--r--tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/form-action-src-get-blocked.sub.html3
-rw-r--r--tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/form-action-src-redirect-blocked.sub.html2
-rw-r--r--tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/meta-outside-head.sub.html8
-rw-r--r--tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/metaHelper.js5
-rw-r--r--tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/plugintypes-notype-data.sub.html4
-rw-r--r--tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/scripthash-unicode-normalization.sub.html18
-rw-r--r--tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/scriptnonce-basic-blocked.sub.html39
-rw-r--r--tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/stylehash-allowed.sub.html2
-rw-r--r--tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/stylehash-allowed.sub.html.sub.headers2
-rw-r--r--tests/wpt/web-platform-tests/content-security-policy/blink-contrib/connect-src-beacon-allowed.sub.html25
-rw-r--r--tests/wpt/web-platform-tests/content-security-policy/blink-contrib/connect-src-beacon-blocked.sub.html24
-rw-r--r--tests/wpt/web-platform-tests/content-security-policy/blink-contrib/connect-src-beacon-redirect-to-blocked.sub.html19
-rw-r--r--tests/wpt/web-platform-tests/content-security-policy/blink-contrib/resources/worker-importscripts.js2
-rw-r--r--tests/wpt/web-platform-tests/content-security-policy/blink-contrib/shared-worker-connect-src-allowed.sub.html12
-rw-r--r--tests/wpt/web-platform-tests/content-security-policy/blink-contrib/shared-worker-connect-src-blocked.sub.html13
-rw-r--r--tests/wpt/web-platform-tests/content-security-policy/blink-contrib/worker-importscripts-blocked.sub.html2
-rw-r--r--tests/wpt/web-platform-tests/content-security-policy/child-src/child-src-worker-blocked.sub.html4
-rw-r--r--tests/wpt/web-platform-tests/content-security-policy/media-src/media-src-7_3_2.html9
-rw-r--r--tests/wpt/web-platform-tests/content-security-policy/media-src/media-src-redir-bug.sub.html4
-rw-r--r--tests/wpt/web-platform-tests/content-security-policy/support/alertAssert.sub.js14
-rw-r--r--tests/wpt/web-platform-tests/content-security-policy/support/logTest.sub.js10
-rw-r--r--tests/wpt/web-platform-tests/dom/events/Event-defaultPrevented-after-dispatch.html26
-rw-r--r--tests/wpt/web-platform-tests/html/OWNERS1
-rw-r--r--tests/wpt/web-platform-tests/html/semantics/embedded-content/the-embed-element/embed-ignored-in-media-element.html22
-rw-r--r--tests/wpt/web-platform-tests/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-1.html33
-rw-r--r--tests/wpt/web-platform-tests/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-2.html33
-rw-r--r--tests/wpt/web-platform-tests/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-3.html33
-rw-r--r--tests/wpt/web-platform-tests/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-4.html33
-rw-r--r--tests/wpt/web-platform-tests/media-source/OWNERS1
-rw-r--r--tests/wpt/web-platform-tests/resource-timing/test_resource_timing.js7
-rw-r--r--tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-add.https.html2
-rw-r--r--tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-delete.https.html2
-rw-r--r--tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-match.https.html2
-rw-r--r--tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-matchAll.https.html2
-rw-r--r--tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-put.https.html2
-rw-r--r--tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-storage-keys.https.html2
-rw-r--r--tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-storage-match.https.html2
-rw-r--r--tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-storage.https.html2
-rw-r--r--tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/credentials.html2
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/fetch-event.https.html72
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-event-test-worker.js17
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-workers/resources/test-helpers.js222
-rw-r--r--tests/wpt/web-platform-tests/tools/manifest/manifest.py70
-rw-r--r--tests/wpt/web-platform-tests/tools/manifest/tests/__init__.py0
-rw-r--r--tests/wpt/web-platform-tests/tools/manifest/tests/test_manifest.py55
-rw-r--r--tests/wpt/web-platform-tests/uievents/order-of-events/focus-events/focus-manual.html81
-rw-r--r--tests/wpt/web-platform-tests/uievents/order-of-events/focus-events/legacy-manual.html84
-rw-r--r--tests/wpt/web-platform-tests/web-animations/animation-effect-timing/easing.html84
-rw-r--r--tests/wpt/web-platform-tests/web-animations/animation-effect-timing/fill.html25
-rw-r--r--tests/wpt/web-platform-tests/web-animations/animation-model/animation-types/discrete-animation.html136
-rw-r--r--tests/wpt/web-platform-tests/web-animations/animation-model/animation-types/not-animatable.html120
-rw-r--r--tests/wpt/web-platform-tests/web-animations/animation-model/keyframes/effect-value-context.html86
-rw-r--r--tests/wpt/web-platform-tests/web-animations/animation/finished.html371
-rw-r--r--tests/wpt/web-platform-tests/web-animations/animation/id.html24
-rw-r--r--tests/wpt/web-platform-tests/web-animations/animation/oncancel.html34
-rw-r--r--tests/wpt/web-platform-tests/web-animations/animation/onfinish.html122
-rw-r--r--tests/wpt/web-platform-tests/web-animations/animation/pause.html99
-rw-r--r--tests/wpt/web-platform-tests/web-animations/animation/ready.html97
-rw-r--r--tests/wpt/web-platform-tests/web-animations/animation/reverse.html150
-rw-r--r--tests/wpt/web-platform-tests/web-animations/keyframe-effect/constructor.html365
-rw-r--r--tests/wpt/web-platform-tests/web-animations/keyframe-effect/effect-easing.html51
-rw-r--r--tests/wpt/web-platform-tests/web-animations/keyframe-effect/keyframe-handling.html40
-rw-r--r--tests/wpt/web-platform-tests/web-animations/resources/effect-easing-tests.js42
-rw-r--r--tests/wpt/web-platform-tests/websockets/constructor/018.html4
92 files changed, 2869 insertions, 642 deletions
diff --git a/tests/wpt/metadata/DOMEvents/tests/approved/EventObject.after.dispatchEvent.html.ini b/tests/wpt/metadata/DOMEvents/tests/approved/EventObject.after.dispatchEvent.html.ini
deleted file mode 100644
index 6f9a31a9658..00000000000
--- a/tests/wpt/metadata/DOMEvents/tests/approved/EventObject.after.dispatchEvent.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[EventObject.after.dispatchEvent.html]
- type: testharness
- [Test Description: As the final step of the event dispatch, the implementation must reset the event object's default-action-prevention state. ]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/DOMEvents/tests/submissions/Microsoft/converted/EventObject.after.dispatchEvent.html.ini b/tests/wpt/metadata/DOMEvents/tests/submissions/Microsoft/converted/EventObject.after.dispatchEvent.html.ini
deleted file mode 100644
index 6f9a31a9658..00000000000
--- a/tests/wpt/metadata/DOMEvents/tests/submissions/Microsoft/converted/EventObject.after.dispatchEvent.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[EventObject.after.dispatchEvent.html]
- type: testharness
- [Test Description: As the final step of the event dispatch, the implementation must reset the event object's default-action-prevention state. ]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/FileAPI/blob/Blob-constructor.html.ini b/tests/wpt/metadata/FileAPI/blob/Blob-constructor.html.ini
index 9d44c1daccf..5f4c6aaa244 100644
--- a/tests/wpt/metadata/FileAPI/blob/Blob-constructor.html.ini
+++ b/tests/wpt/metadata/FileAPI/blob/Blob-constructor.html.ini
@@ -42,6 +42,11 @@
[Array with mixed types]
expected: FAIL
- [no-argument Blob constructor without 'new']
+ [Blob constructor with no arguments, without 'new']
+ bug: https://github.com/servo/servo/issues/10744
+ expected: FAIL
+
+ [Blob constructor with undefined as first argument]
+ bug: https://github.com/servo/servo/issues/10779
expected: FAIL
diff --git a/tests/wpt/metadata/MANIFEST.json b/tests/wpt/metadata/MANIFEST.json
index 1f4b82f38c4..93aaaca93ef 100644
--- a/tests/wpt/metadata/MANIFEST.json
+++ b/tests/wpt/metadata/MANIFEST.json
@@ -3226,6 +3226,14 @@
"url": "/touch-events/single-touch-manual.html"
},
{
+ "path": "uievents/order-of-events/focus-events/focus-manual.html",
+ "url": "/uievents/order-of-events/focus-events/focus-manual.html"
+ },
+ {
+ "path": "uievents/order-of-events/focus-events/legacy-manual.html",
+ "url": "/uievents/order-of-events/focus-events/legacy-manual.html"
+ },
+ {
"path": "uievents/order-of-events/mouse-events/click-on-body-manual.html",
"url": "/uievents/order-of-events/mouse-events/click-on-body-manual.html"
},
@@ -3696,6 +3704,56 @@
"url": "/compat/webkit-text-fill-color-property-001d.html"
},
{
+ "path": "compat/webkit-text-fill-color-property-002.html",
+ "references": [
+ [
+ "/compat/webkit-text-fill-color-property-002-ref.html",
+ "=="
+ ]
+ ],
+ "url": "/compat/webkit-text-fill-color-property-002.html"
+ },
+ {
+ "path": "compat/webkit-text-fill-color-property-003.html",
+ "references": [
+ [
+ "/compat/webkit-text-fill-color-property-003-ref.html",
+ "=="
+ ]
+ ],
+ "url": "/compat/webkit-text-fill-color-property-003.html"
+ },
+ {
+ "path": "compat/webkit-text-fill-color-property-004.html",
+ "references": [
+ [
+ "/compat/webkit-text-fill-color-property-004-ref.html",
+ "=="
+ ]
+ ],
+ "url": "/compat/webkit-text-fill-color-property-004.html"
+ },
+ {
+ "path": "compat/webkit-text-fill-color-property-005.html",
+ "references": [
+ [
+ "/compat/webkit-text-fill-color-property-005-ref.html",
+ "=="
+ ]
+ ],
+ "url": "/compat/webkit-text-fill-color-property-005.html"
+ },
+ {
+ "path": "compat/webkit-text-fill-color-property-006.html",
+ "references": [
+ [
+ "/compat/webkit-text-fill-color-property-006-ref.html",
+ "=="
+ ]
+ ],
+ "url": "/compat/webkit-text-fill-color-property-006.html"
+ },
+ {
"path": "custom-elements/registering-custom-elements/unresolved-element-pseudoclass/unresolved-element-pseudoclass-css-test-custom-tag.html",
"references": [
[
@@ -11068,10 +11126,6 @@
"url": "/DOMEvents/tests/approved/EventListener.eventHandler.html"
},
{
- "path": "DOMEvents/tests/approved/EventObject.after.dispatchEvent.html",
- "url": "/DOMEvents/tests/approved/EventObject.after.dispatchEvent.html"
- },
- {
"path": "DOMEvents/tests/approved/EventObject.multiple.dispatchEvent.html",
"url": "/DOMEvents/tests/approved/EventObject.multiple.dispatchEvent.html"
},
@@ -11108,10 +11162,6 @@
"url": "/DOMEvents/tests/submissions/Microsoft/converted/EventListener.eventHandler.html"
},
{
- "path": "DOMEvents/tests/submissions/Microsoft/converted/EventObject.after.dispatchEvent.html",
- "url": "/DOMEvents/tests/submissions/Microsoft/converted/EventObject.after.dispatchEvent.html"
- },
- {
"path": "DOMEvents/tests/submissions/Microsoft/converted/EventObject.multiple.dispatchEvent.html",
"url": "/DOMEvents/tests/submissions/Microsoft/converted/EventObject.multiple.dispatchEvent.html"
},
@@ -14048,6 +14098,10 @@
"url": "/dom/events/Event-constructors.html"
},
{
+ "path": "dom/events/Event-defaultPrevented-after-dispatch.html",
+ "url": "/dom/events/Event-defaultPrevented-after-dispatch.html"
+ },
+ {
"path": "dom/events/Event-defaultPrevented.html",
"url": "/dom/events/Event-defaultPrevented.html"
},
@@ -18732,6 +18786,10 @@
"url": "/html/semantics/embedded-content/the-embed-element/embed-document.html"
},
{
+ "path": "html/semantics/embedded-content/the-embed-element/embed-ignored-in-media-element.html",
+ "url": "/html/semantics/embedded-content/the-embed-element/embed-ignored-in-media-element.html"
+ },
+ {
"path": "html/semantics/embedded-content/the-iframe-element/iframe_javascript_url_01.htm",
"url": "/html/semantics/embedded-content/the-iframe-element/iframe_javascript_url_01.htm"
},
@@ -19992,6 +20050,22 @@
"url": "/html/webappapis/scripting/processing-model-2/window-onerror-runtime-error.html"
},
{
+ "path": "html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-1.html",
+ "url": "/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-1.html"
+ },
+ {
+ "path": "html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-2.html",
+ "url": "/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-2.html"
+ },
+ {
+ "path": "html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-3.html",
+ "url": "/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-3.html"
+ },
+ {
+ "path": "html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-4.html",
+ "url": "/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-4.html"
+ },
+ {
"path": "html/webappapis/system-state-and-capabilities/the-navigator-object/NavigatorID.html",
"url": "/html/webappapis/system-state-and-capabilities/the-navigator-object/NavigatorID.html"
},
@@ -28720,10 +28794,18 @@
"url": "/web-animations/animation-effect-timing/duration.html"
},
{
+ "path": "web-animations/animation-effect-timing/easing.html",
+ "url": "/web-animations/animation-effect-timing/easing.html"
+ },
+ {
"path": "web-animations/animation-effect-timing/endDelay.html",
"url": "/web-animations/animation-effect-timing/endDelay.html"
},
{
+ "path": "web-animations/animation-effect-timing/fill.html",
+ "url": "/web-animations/animation-effect-timing/fill.html"
+ },
+ {
"path": "web-animations/animation-effect-timing/getAnimations.html",
"url": "/web-animations/animation-effect-timing/getAnimations.html"
},
@@ -28740,6 +28822,18 @@
"url": "/web-animations/animation-effect-timing/iterations.html"
},
{
+ "path": "web-animations/animation-model/animation-types/discrete-animation.html",
+ "url": "/web-animations/animation-model/animation-types/discrete-animation.html"
+ },
+ {
+ "path": "web-animations/animation-model/animation-types/not-animatable.html",
+ "url": "/web-animations/animation-model/animation-types/not-animatable.html"
+ },
+ {
+ "path": "web-animations/animation-model/keyframes/effect-value-context.html",
+ "url": "/web-animations/animation-model/keyframes/effect-value-context.html"
+ },
+ {
"path": "web-animations/animation-timeline/document-timeline.html",
"url": "/web-animations/animation-timeline/document-timeline.html"
},
@@ -28760,6 +28854,26 @@
"url": "/web-animations/animation/finish.html"
},
{
+ "path": "web-animations/animation/finished.html",
+ "url": "/web-animations/animation/finished.html"
+ },
+ {
+ "path": "web-animations/animation/id.html",
+ "url": "/web-animations/animation/id.html"
+ },
+ {
+ "path": "web-animations/animation/oncancel.html",
+ "url": "/web-animations/animation/oncancel.html"
+ },
+ {
+ "path": "web-animations/animation/onfinish.html",
+ "url": "/web-animations/animation/onfinish.html"
+ },
+ {
+ "path": "web-animations/animation/pause.html",
+ "url": "/web-animations/animation/pause.html"
+ },
+ {
"path": "web-animations/animation/play.html",
"url": "/web-animations/animation/play.html"
},
@@ -28772,6 +28886,14 @@
"url": "/web-animations/animation/playbackRate.html"
},
{
+ "path": "web-animations/animation/ready.html",
+ "url": "/web-animations/animation/ready.html"
+ },
+ {
+ "path": "web-animations/animation/reverse.html",
+ "url": "/web-animations/animation/reverse.html"
+ },
+ {
"path": "web-animations/keyframe-effect/constructor.html",
"url": "/web-animations/keyframe-effect/constructor.html"
},
@@ -35091,6 +35213,7 @@
},
"local_changes": {
"deleted": [],
+ "deleted_reftests": {},
"items": {},
"reftest_nodes": {}
},
@@ -35587,6 +35710,66 @@
"url": "/compat/webkit-text-fill-color-property-001d.html"
}
],
+ "compat/webkit-text-fill-color-property-002.html": [
+ {
+ "path": "compat/webkit-text-fill-color-property-002.html",
+ "references": [
+ [
+ "/compat/webkit-text-fill-color-property-002-ref.html",
+ "=="
+ ]
+ ],
+ "url": "/compat/webkit-text-fill-color-property-002.html"
+ }
+ ],
+ "compat/webkit-text-fill-color-property-003.html": [
+ {
+ "path": "compat/webkit-text-fill-color-property-003.html",
+ "references": [
+ [
+ "/compat/webkit-text-fill-color-property-003-ref.html",
+ "=="
+ ]
+ ],
+ "url": "/compat/webkit-text-fill-color-property-003.html"
+ }
+ ],
+ "compat/webkit-text-fill-color-property-004.html": [
+ {
+ "path": "compat/webkit-text-fill-color-property-004.html",
+ "references": [
+ [
+ "/compat/webkit-text-fill-color-property-004-ref.html",
+ "=="
+ ]
+ ],
+ "url": "/compat/webkit-text-fill-color-property-004.html"
+ }
+ ],
+ "compat/webkit-text-fill-color-property-005.html": [
+ {
+ "path": "compat/webkit-text-fill-color-property-005.html",
+ "references": [
+ [
+ "/compat/webkit-text-fill-color-property-005-ref.html",
+ "=="
+ ]
+ ],
+ "url": "/compat/webkit-text-fill-color-property-005.html"
+ }
+ ],
+ "compat/webkit-text-fill-color-property-006.html": [
+ {
+ "path": "compat/webkit-text-fill-color-property-006.html",
+ "references": [
+ [
+ "/compat/webkit-text-fill-color-property-006-ref.html",
+ "=="
+ ]
+ ],
+ "url": "/compat/webkit-text-fill-color-property-006.html"
+ }
+ ],
"custom-elements/registering-custom-elements/unresolved-element-pseudoclass/unresolved-element-pseudoclass-css-test-custom-tag.html": [
{
"path": "custom-elements/registering-custom-elements/unresolved-element-pseudoclass/unresolved-element-pseudoclass-css-test-custom-tag.html",
@@ -41336,7 +41519,7 @@
}
]
},
- "rev": "20fa4a3a71ab7a2f75b4febbe2e98aeeaf022c2b",
+ "rev": "0a518aaff73532a26e175789f7e75fa99593ac64",
"url_base": "/",
"version": 3
}
diff --git a/tests/wpt/metadata/cssom-view/elementScroll.html.ini b/tests/wpt/metadata/cssom-view/elementScroll.html.ini
index 8d1d147753b..706def9d330 100644
--- a/tests/wpt/metadata/cssom-view/elementScroll.html.ini
+++ b/tests/wpt/metadata/cssom-view/elementScroll.html.ini
@@ -2,3 +2,4 @@
type: testharness
[Element scroll maximum test]
expected: FAIL
+
diff --git a/tests/wpt/metadata/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-1.html.ini b/tests/wpt/metadata/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-1.html.ini
new file mode 100644
index 00000000000..d0e9c948e3a
--- /dev/null
+++ b/tests/wpt/metadata/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-1.html.ini
@@ -0,0 +1,6 @@
+[window-onerror-with-cross-frame-event-listeners-1.html]
+ type: testharness
+ bug: https://github.com/servo/servo/issues/3311
+ [The error event from an event listener should fire on that listener's global]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-2.html.ini b/tests/wpt/metadata/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-2.html.ini
new file mode 100644
index 00000000000..3d72563832c
--- /dev/null
+++ b/tests/wpt/metadata/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-2.html.ini
@@ -0,0 +1,6 @@
+[window-onerror-with-cross-frame-event-listeners-2.html]
+ type: testharness
+ bug: https://github.com/servo/servo/issues/3311
+ [The error event from an event listener should fire on that listener's global]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-3.html.ini b/tests/wpt/metadata/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-3.html.ini
new file mode 100644
index 00000000000..10f8529a133
--- /dev/null
+++ b/tests/wpt/metadata/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-3.html.ini
@@ -0,0 +1,6 @@
+[window-onerror-with-cross-frame-event-listeners-3.html]
+ type: testharness
+ bug: https://github.com/servo/servo/issues/3311
+ [The error event from an event listener should fire on that listener's global]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-4.html.ini b/tests/wpt/metadata/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-4.html.ini
new file mode 100644
index 00000000000..eff06558b41
--- /dev/null
+++ b/tests/wpt/metadata/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-4.html.ini
@@ -0,0 +1,6 @@
+[window-onerror-with-cross-frame-event-listeners-4.html]
+ type: testharness
+ bug: https://github.com/servo/servo/issues/3311
+ [The error event from an event listener should fire on that listener's global]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/mozilla-sync b/tests/wpt/metadata/mozilla-sync
index 0758a6a54f4..fe5dedf7818 100644
--- a/tests/wpt/metadata/mozilla-sync
+++ b/tests/wpt/metadata/mozilla-sync
@@ -1 +1 @@
-3d4416e1b0ae758e68900f725979238cc0128f8b \ No newline at end of file
+9c172f49d08fe9019b0ba193ea4d75c6ddb95cda \ No newline at end of file
diff --git a/tests/wpt/metadata/websockets/constructor/018.html.ini b/tests/wpt/metadata/websockets/constructor/018.html.ini
new file mode 100644
index 00000000000..ba4b969fdd2
--- /dev/null
+++ b/tests/wpt/metadata/websockets/constructor/018.html.ini
@@ -0,0 +1,5 @@
+[018.html]
+ type: testharness
+ [WebSockets: NULL char in url]
+ expected: FAIL
+
diff --git a/tests/wpt/mozilla/meta/MANIFEST.json b/tests/wpt/mozilla/meta/MANIFEST.json
index 0c5279fc574..aa4e376ac97 100644
--- a/tests/wpt/mozilla/meta/MANIFEST.json
+++ b/tests/wpt/mozilla/meta/MANIFEST.json
@@ -8,6 +8,7 @@
},
"local_changes": {
"deleted": [],
+ "deleted_reftests": {},
"items": {
"reftest": {
"css/abs-overflow-stackingcontext.html": [
diff --git a/tests/wpt/web-platform-tests/DOMEvents/tests/approved/EventObject.after.dispatchEvent.html b/tests/wpt/web-platform-tests/DOMEvents/tests/approved/EventObject.after.dispatchEvent.html
deleted file mode 100644
index d8ab8d4f26a..00000000000
--- a/tests/wpt/web-platform-tests/DOMEvents/tests/approved/EventObject.after.dispatchEvent.html
+++ /dev/null
@@ -1,44 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title> Event.defaultPrevented is reset after dipatchEvent() </title>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-</head>
-<body>
-<div id=log></div>
-
-<input id="target" type="hidden" value=""/>
-
-<script>
- var EVENT = "foo";
- var TARGET = document.getElementById("target");
- var PreState;
- var PosState;
-
- var description = "Test Description: " +
- "As the final step of the event dispatch, the implementation must reset the event " +
- "object's default-action-prevention state. ";
-
- test(function()
- {
- var evt = document.createEvent("Event");
- evt.initEvent(EVENT, true, true);
-
- TARGET.addEventListener(EVENT, TestEvent, true);
- TARGET.dispatchEvent(evt);
-
- PosState = evt.defaultPrevented;
-
- assert_array_equals([evt.target, PreState, PosState], [TARGET, true, false]);
-
- }, description);
-
- function TestEvent(evt)
- {
- evt.preventDefault();
- PreState = evt.defaultPrevented;
- }
-</script>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/DOMEvents/tests/submissions/Microsoft/converted/EventObject.after.dispatchEvent.html b/tests/wpt/web-platform-tests/DOMEvents/tests/submissions/Microsoft/converted/EventObject.after.dispatchEvent.html
deleted file mode 100644
index a2e44c9c8cf..00000000000
--- a/tests/wpt/web-platform-tests/DOMEvents/tests/submissions/Microsoft/converted/EventObject.after.dispatchEvent.html
+++ /dev/null
@@ -1,45 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title> Event.defaultPrevented is reset after dipatchEvent() </title>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-</head>
-<body>
-<div id=log></div>
-
-<input id="target" type="hidden" value=""/>
-
-<script>
-
- var EVENT = "foo";
- var TARGET = document.getElementById("target");
- var PreState;
- var PosState;
-
- var description = "Test Description: " +
- "As the final step of the event dispatch, the implementation must reset the event " +
- "object's default-action-prevention state. ";
-
- test(function()
- {
- var evt = document.createEvent("Event");
- evt.initEvent(EVENT, true, true);
-
- TARGET.addEventListener(EVENT, TestEvent, true);
- TARGET.dispatchEvent(evt);
-
- PosState = evt.defaultPrevented;
-
- assert_array_equals([evt.target, PreState, PosState], [TARGET, true, false]);
-
- }, description);
-
- function TestEvent(evt)
- {
- evt.preventDefault();
- PreState = evt.defaultPrevented;
- }
-</script>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/FileAPI/blob/Blob-constructor.html b/tests/wpt/web-platform-tests/FileAPI/blob/Blob-constructor.html
index 799091d55ac..9c2b0a138c9 100644
--- a/tests/wpt/web-platform-tests/FileAPI/blob/Blob-constructor.html
+++ b/tests/wpt/web-platform-tests/FileAPI/blob/Blob-constructor.html
@@ -23,22 +23,28 @@ test(function() {
assert_equals(String(blob), '[object Blob]');
assert_equals(blob.size, 0);
assert_equals(blob.type, "");
-}, "no-argument Blob constructor");
+}, "Blob constructor with no arguments");
test(function() {
assert_throws(new TypeError(), function() { var blob = Blob(); });
-}, "no-argument Blob constructor without 'new'");
+}, "Blob constructor with no arguments, without 'new'");
test(function() {
var blob = new Blob;
assert_true(blob instanceof Blob);
assert_equals(blob.size, 0);
assert_equals(blob.type, "");
-}, "no-argument Blob constructor without brackets");
+}, "Blob constructor without brackets");
+test(function() {
+ var blob = new Blob(undefined);
+ assert_true(blob instanceof Blob);
+ assert_equals(String(blob), '[object Blob]');
+ assert_equals(blob.size, 0);
+ assert_equals(blob.type, "");
+}, "Blob constructor with undefined as first argument");
// blobParts argument (WebIDL).
test(function() {
var args = [
null,
- undefined,
true,
false,
0,
diff --git a/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-002-ref.html b/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-002-ref.html
new file mode 100644
index 00000000000..00c5072f85d
--- /dev/null
+++ b/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-002-ref.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>webkit-text-fill-color on selected text reference</title>
+<link rel="author" title="Jeremy Chen" href="jeremychen@mozilla.com">
+<link rel="author" title="Mozilla" href="https://www.mozilla.org">
+<style>
+p {
+ color: green;
+}
+</style>
+<body onload="onload()">
+<p>Pass if color of <span id="selectMe">selected text</span> is green or inverted (depending on the platform convention), but not red</p>
+<script type="text/javascript">
+function onload() {
+ var elt = document.getElementById("selectMe");
+ var range = document.createRange();
+ range.selectNode(elt);
+ window.getSelection().removeAllRanges();
+ window.getSelection().addRange(range);
+ document.documentElement.classList.remove('reftest-wait');
+}
+</script>
+</body>
+</html>
diff --git a/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-002.html b/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-002.html
new file mode 100644
index 00000000000..8ed14ccc83c
--- /dev/null
+++ b/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-002.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>webkit-text-fill-color should take effect while rendering selected text</title>
+<link rel="author" title="Jeremy Chen" href="jeremychen@mozilla.com">
+<link rel="author" title="Mozilla" href="https://www.mozilla.org">
+<link rel="help" href="https://compat.spec.whatwg.org/#the-webkit-text-fill-color">
+<meta name="assert" content="The color of selected text should be green">
+<link rel="match" href="webkit-text-fill-color-property-002-ref.html">
+<style>
+p {
+ color: red;
+ -webkit-text-fill-color: green;
+}
+</style>
+<body onload="onload()">
+<p>Pass if color of <span id="selectMe">selected text</span> is green or inverted (depending on the platform convention), but not red</p>
+<script type="text/javascript">
+function onload() {
+ var elt = document.getElementById("selectMe");
+ var range = document.createRange();
+ range.selectNode(elt);
+ window.getSelection().removeAllRanges();
+ window.getSelection().addRange(range);
+ document.documentElement.classList.remove('reftest-wait');
+}
+</script>
+</body>
+</html>
diff --git a/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-003-ref.html b/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-003-ref.html
new file mode 100644
index 00000000000..bbfd78e37ff
--- /dev/null
+++ b/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-003-ref.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>webkit-text-fill-color on ::-moz-selection selected text reference</title>
+<link rel="author" title="Jeremy Chen" href="jeremychen@mozilla.com">
+<link rel="author" title="Mozilla" href="https://www.mozilla.org">
+<style>
+::-moz-selection {
+ color: green; background: skyblue;
+}
+::selection {
+ color: green; background: skyblue;
+}
+</style>
+<body onload="onload()">
+<p>Pass if color of <span id="selectMe">selected text</span> is green!!!</p>
+<script type="text/javascript">
+function onload() {
+ var elt = document.getElementById("selectMe");
+ var range = document.createRange();
+ range.selectNode(elt);
+ window.getSelection().removeAllRanges();
+ window.getSelection().addRange(range);
+ document.documentElement.classList.remove('reftest-wait');
+}
+</script>
+</body>
+</html>
diff --git a/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-003.html b/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-003.html
new file mode 100644
index 00000000000..dcbd70b18f5
--- /dev/null
+++ b/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-003.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>webkit-text-fill-color should take effect while rendering ::-moz-selection selected text</title>
+<link rel="author" title="Jeremy Chen" href="jeremychen@mozilla.com">
+<link rel="author" title="Mozilla" href="https://www.mozilla.org">
+<link rel="help" href="https://compat.spec.whatwg.org/#the-webkit-text-fill-color">
+<meta name="assert" content="The color of selected text should be green">
+<link rel="match" href="webkit-text-fill-color-property-003-ref.html">
+<style>
+::-moz-selection {
+ background: skyblue;
+ color: red;
+ -webkit-text-fill-color: green;
+}
+::selection {
+ background: skyblue;
+ color: red;
+ -webkit-text-fill-color: green;
+}
+</style>
+<body onload="onload()">
+<p>Pass if color of <span id="selectMe">selected text</span> is green!!!</p>
+<script type="text/javascript">
+function onload() {
+ var elt = document.getElementById("selectMe");
+ var range = document.createRange();
+ range.selectNode(elt);
+ window.getSelection().removeAllRanges();
+ window.getSelection().addRange(range);
+ document.documentElement.classList.remove('reftest-wait');
+}
+</script>
+</body>
+</html>
diff --git a/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-004-ref.html b/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-004-ref.html
new file mode 100644
index 00000000000..583cf9a358d
--- /dev/null
+++ b/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-004-ref.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>webkit-text-fill-color on MathML reference</title>
+<link rel="author" title="Jeremy Chen" href="jeremychen@mozilla.com">
+<link rel="author" title="Mozilla" href="https://www.mozilla.org">
+<style>
+math {
+ font-size: 50px;
+ color: green;
+}
+</style>
+<body>
+<p>Pass if color of operators and operands are all green!!!</p>
+ <math>
+ <mrow>
+ <mrow>
+ <msup>
+ <mi>a</mi>
+ <mn>2</mn>
+ </msup>
+ <mo>+</mo>
+ <msup>
+ <mi>b</mi>
+ <mn>2</mn>
+ </msup>
+ </mrow>
+ <mo>=</mo>
+ <msup>
+ <mi>c</mi>
+ <mn>2</mn>
+ </msup>
+ </mrow>
+ </math>
+</body>
diff --git a/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-004.html b/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-004.html
new file mode 100644
index 00000000000..739418d98e5
--- /dev/null
+++ b/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-004.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>webkit-text-fill-color should take effect while rendering MathML</title>
+<link rel="author" title="Jeremy Chen" href="jeremychen@mozilla.com">
+<link rel="author" title="Mozilla" href="https://www.mozilla.org">
+<link rel="help" href="https://compat.spec.whatwg.org/#the-webkit-text-fill-color">
+<meta name="assert" content="The color of MathML should be green">
+<link rel="match" href="webkit-text-fill-color-property-004-ref.html">
+<style>
+math {
+ font-size: 50px;
+ color: red;
+ -webkit-text-fill-color: green;
+}
+</style>
+<body>
+<p>Pass if color of operators and operands are all green!!!</p>
+ <math>
+ <mrow>
+ <mrow>
+ <msup>
+ <mi>a</mi>
+ <mn>2</mn>
+ </msup>
+ <mo>+</mo>
+ <msup>
+ <mi>b</mi>
+ <mn>2</mn>
+ </msup>
+ </mrow>
+ <mo>=</mo>
+ <msup>
+ <mi>c</mi>
+ <mn>2</mn>
+ </msup>
+ </mrow>
+ </math>
+</body>
diff --git a/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-005-ref.html b/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-005-ref.html
new file mode 100644
index 00000000000..f173137fabf
--- /dev/null
+++ b/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-005-ref.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>webkit-text-fill-color on text-decoration underline reference</title>
+<link rel="author" title="Jeremy Chen" href="jeremychen@mozilla.com">
+<link rel="author" title="Mozilla" href="https://www.mozilla.org">
+<style type="text/css">
+p {
+ font-size: 50px;
+ text-decoration: underline;
+ color: green;
+}
+</style>
+<div><p>Pass if text underline is green!!!</p></div>
diff --git a/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-005.html b/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-005.html
new file mode 100644
index 00000000000..b3549d68b17
--- /dev/null
+++ b/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-005.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>webkit-text-fill-color should take effect while rendering text-decoration underline</title>
+<link rel="author" title="Jeremy Chen" href="jeremychen@mozilla.com">
+<link rel="author" title="Mozilla" href="https://www.mozilla.org">
+<link rel="help" href="https://compat.spec.whatwg.org/#the-webkit-text-fill-color">
+<meta name="assert" content="The color of text-decoration underline should be green">
+<link rel="match" href="webkit-text-fill-color-property-005-ref.html">
+<style type="text/css">
+p {
+ font-size: 50px;
+ text-decoration: underline;
+ color: red;
+ -webkit-text-fill-color: green;
+}
+</style>
+<div><p>Pass if text underline is green!!!</p></div>
diff --git a/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-006-ref.html b/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-006-ref.html
new file mode 100644
index 00000000000..602d296bdb4
--- /dev/null
+++ b/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-006-ref.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>webkit-text-fill-color on text-overflow ellipsis reference</title>
+<link rel="author" title="Jeremy Chen" href="jeremychen@mozilla.com">
+<link rel="author" title="Mozilla" href="https://www.mozilla.org">
+<style>
+div {
+ font-size: 10px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ width: 150px;
+ color: green;
+}
+span {
+ font-family: Ahem;
+ font-size: 30px;
+}
+</style>
+<body>
+<p>Test passes if there is a <strong>green ellipsis</strong> after "TestChecks".</p>
+<div>
+ <span>TestChecksThatTextColorAndEllipsisColorShouldBeTheSame</span>
+</div>
+</body>
diff --git a/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-006.html b/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-006.html
new file mode 100644
index 00000000000..4eb37e9e951
--- /dev/null
+++ b/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-006.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>webkit-text-fill-color should take effect while rendering text-overflow ellipsis</title>
+<link rel="author" title="Jeremy Chen" href="jeremychen@mozilla.com">
+<link rel="author" title="Mozilla" href="https://www.mozilla.org">
+<link rel="help" href="https://compat.spec.whatwg.org/#the-webkit-text-fill-color">
+<meta name="assert" content="The color of text-overflow ellipsis should be green">
+<link rel="match" href="webkit-text-fill-color-property-006-ref.html">
+<style>
+div {
+ font-size: 10px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ width: 150px;
+ color: red;
+ -webkit-text-fill-color: green;
+}
+span {
+ font-family: Ahem;
+ font-size: 30px;
+}
+</style>
+<body>
+<p>Test passes if there is a <strong>green ellipsis</strong> after "TestChecks".</p>
+<div>
+ <span>TestChecksThatTextColorAndEllipsisColorShouldBeTheSame</span>
+</div>
+</body>
diff --git a/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/form-action-src-allowed.sub.html b/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/form-action-src-allowed.sub.html
index 57889e5966c..19cf6811c57 100644
--- a/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/form-action-src-allowed.sub.html
+++ b/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/form-action-src-allowed.sub.html
@@ -32,7 +32,7 @@ form-action 'self'; script-src 'self' 'unsafe-inline'; connect-src 'self';
<input type="text" name="fieldname" value="fieldvalue">
<input type="submit" id="submit" value="submit">
</form>
- <p>Tests that allowed form actions work correctly. If this test passes, you will see a page indicating a form was POSTed.</p>
+ <p>Tests that allowed form actions work correctly.</p>
<div id="log"></div>
<script async defer src="../support/checkReport.sub.js?reportExists=false"></script>
</body>
diff --git a/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/form-action-src-blocked.sub.html b/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/form-action-src-blocked.sub.html
index 33ce163af24..0960a8a02f2 100644
--- a/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/form-action-src-blocked.sub.html
+++ b/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/form-action-src-blocked.sub.html
@@ -31,7 +31,7 @@ form-action 'none'; script-src 'self' 'unsafe-inline'; connect-src 'self';
<input type="text" name="fieldname" value="fieldvalue">
<input type="submit" id="submit" value="submit">
</form>
- <p>Tests that blocking form actions works correctly. If this test passes, a CSP violation will be generated, and will not see a page indicating a form was POSTed.</p>
+ <p>Tests that blocking form actions works correctly.</p>
<div id="log"></div>
<script async defer src="../support/checkReport.sub.js?reportExists=true&amp;reportField=violated-directive&amp;reportValue=form-action%20&apos;none&apos;"></script>
diff --git a/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/form-action-src-get-allowed.sub.html b/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/form-action-src-get-allowed.sub.html
index 2f2804b64bb..a7d3e584b83 100644
--- a/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/form-action-src-get-allowed.sub.html
+++ b/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/form-action-src-get-allowed.sub.html
@@ -33,7 +33,8 @@ form-action 'self'; script-src 'self' 'unsafe-inline'; connect-src 'self';
<input type="text" name="fieldname" value="fieldvalue">
<input type="submit" id="submit" value="submit">
</form>
- <p>Tests that allowed form actions work correctly. If this test passes, you will see a page indicating a form was POSTed.</p>
+ <p>Tests that allowed form actions work correctly
+ with GET and a redirect.</p>
<div id="log"></div>
<script async defer src="../support/checkReport.sub.js?reportExists=false"></script>
</body>
diff --git a/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/form-action-src-get-blocked.sub.html b/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/form-action-src-get-blocked.sub.html
index 559e159f057..0910eb41964 100644
--- a/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/form-action-src-get-blocked.sub.html
+++ b/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/form-action-src-get-blocked.sub.html
@@ -33,7 +33,8 @@ form-action 'none'; script-src 'self' 'unsafe-inline'; connect-src 'self';
<input type="text" name="fieldname" value="fieldvalue">
<input type="submit" id="submit" value="submit">
</form>
- <p>Tests that allowed form actions work correctly. If this test passes, you will see a page indicating a form was POSTed.</p>
+ <p>Tests that disallowed form actions are blocked
+ with GET and redirects.</p>
<div id="log"></div>
<script async defer src="../support/checkReport.sub.js?reportExists=true&amp;reportField=violated-directive&amp;reportValue=form-action%20&apos;none&apos;
"></script>
diff --git a/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/form-action-src-redirect-blocked.sub.html b/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/form-action-src-redirect-blocked.sub.html
index 1d9d5693ac1..e311817eb59 100644
--- a/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/form-action-src-redirect-blocked.sub.html
+++ b/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/form-action-src-redirect-blocked.sub.html
@@ -33,7 +33,7 @@ form-action 'self'; script-src 'self' 'unsafe-inline'; connect-src 'self';
<input type="text" name="fieldname" value="fieldvalue">
<input type="submit" id="submit" value="submit">
</form>
- <p>Tests that blocking form redirect works correctly. If this test passes, a CSP violation will be generated, and will not see a page indicating a form was POSTed.</p>
+ <p>Tests that blocking a POST form with a redirect works correctly. If this test passes, a CSP violation will be generated.</p>
<div id="log"></div>
<script async defer src="../support/checkReport.sub.js?reportExists=true&amp;reportField=violated-directive&amp;reportValue=form-action%20'self'"></script>
</body>
diff --git a/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/meta-outside-head.sub.html b/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/meta-outside-head.sub.html
index ac103981c3c..41618d4ef77 100644
--- a/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/meta-outside-head.sub.html
+++ b/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/meta-outside-head.sub.html
@@ -14,14 +14,14 @@ script-src 'self' 'unsafe-inline' 'none'; connect-src 'self';
</head>
<body>
- <meta http-equiv="Content-Security-Policy" content="script-src 'none'">
+ <meta http-equiv="Content-Security-Policy" content="script-src 'self'">
<p>This test checks that Content Security Policy delivered via a meta element is not enforced if the element is outside the document&apos;s head.</p>
<script>
- alert_assert("PASS (1/1)");
-
+ var aa = "PASS (1/1)";
</script>
+ <script src="metaHelper.js"></script>
<div id="log"></div>
- <script async defer src="../support/checkReport.sub.js?reportExists=false"></script>
+ <script src="../support/checkReport.sub.js?reportExists=false"></script>
</body>
</html>
diff --git a/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/metaHelper.js b/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/metaHelper.js
new file mode 100644
index 00000000000..9191a39c73b
--- /dev/null
+++ b/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/metaHelper.js
@@ -0,0 +1,5 @@
+if (typeof aa != 'undefined') {
+ alert_assert(aa);
+} else {
+ alert_assert("Failed - allowed inline script blocked by meta policy outside head.");
+}
diff --git a/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/plugintypes-notype-data.sub.html b/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/plugintypes-notype-data.sub.html
index 59179c71615..eb60d5d4cff 100644
--- a/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/plugintypes-notype-data.sub.html
+++ b/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/plugintypes-notype-data.sub.html
@@ -6,7 +6,7 @@
<title>plugintypes-notype-data</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
- <script src='../support/logTest.sub.js?logs=["PASS"]'></script>
+ <script src='../support/logTest.sub.js?logs=["PASS: object tag onerror handler fired"]'></script>
<script src="../support/alertAssert.sub.js?alerts=[]"></script>
<!-- enforcing policy:
plugin-types application/x-invalid-type; script-src 'self' 'unsafe-inline'; connect-src 'self';
@@ -15,7 +15,7 @@ plugin-types application/x-invalid-type; script-src 'self' 'unsafe-inline'; conn
<body>
Given a `plugin-types` directive, plugins have to declare a type explicitly. No declared type, no load. This test passes if there&apos;s a CSP report and &quot;FAIL!&quot; isn&apos;t logged.
- <object data="data:application/x-webkit-test-netscape" onload="log('FAIL');" onerror="log('PASS');"></object>
+ <object data="data:application/x-webkit-test-netscape" onload="log('FAIL');" onerror="log('PASS: object tag onerror handler fired');"></object>
<div id="log"></div>
<script async defer src="../support/checkReport.sub.js?reportExists=true&amp;reportField=violated-directive&amp;reportValue=plugin-types+application/x-invalid-type"></script>
</body>
diff --git a/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/scripthash-unicode-normalization.sub.html b/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/scripthash-unicode-normalization.sub.html
index 8a064c70172..bd1e0365c2e 100644
--- a/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/scripthash-unicode-normalization.sub.html
+++ b/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/scripthash-unicode-normalization.sub.html
@@ -7,7 +7,6 @@
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
- </script>
<!-- enforcing policy:
script-src 'self' 'nonce-nonceynonce' 'sha256-dWTP4Di8KBjaiXvQ5mRquI9OoBSo921ahYxLfYSiuT8='; connect-src 'self';
-->
@@ -34,12 +33,9 @@ script-src 'self' 'nonce-nonceynonce' 'sha256-dWTP4Di8KBjaiXvQ5mRquI9OoBSo921ahY
var scriptContent2 = "window.finish('" + nonMatchingContent + "');";
var script1 = document.createElement('script');
- script1.innerHTML = scriptContent1;
var script2 = document.createElement('script');
- script2.innerHTML = scriptContent2;
- script1.test = async_test("Inline script with hash in CSP");
- script2.test = async_test("Inline script without hash in CSP");
+ script1.test = async_test("Only matching content runs even with NFC normalization.");
var failure = function() {
assert_unreached();
@@ -51,16 +47,18 @@ script-src 'self' 'nonce-nonceynonce' 'sha256-dWTP4Di8KBjaiXvQ5mRquI9OoBSo921ahY
script1.test.done();
});
} else {
- assert_unreached();
+ script1.test.step(function() {
+ assert_unreached("nonMatchingContent script ran");
+ });
}
}
script1.onerror = failure;
- script2.onerror = script2.test.step_func(function() {
- script2.test.done();
- });
- document.body.appendChild(script1);
+
document.body.appendChild(script2);
+ script2.textContent = scriptContent2;
+ document.body.appendChild(script1);
+ script1.textContent = scriptContent1;
</script>
<p>
diff --git a/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/scriptnonce-basic-blocked.sub.html b/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/scriptnonce-basic-blocked.sub.html
index 18ad1d4f66c..4815ca10013 100644
--- a/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/scriptnonce-basic-blocked.sub.html
+++ b/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/scriptnonce-basic-blocked.sub.html
@@ -6,49 +6,16 @@
<title>scriptnonce-basic-blocked</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
- <script nonce='noncynonce'>
- function log(msg) {
- test(function() {
- assert_unreached(msg)
- });
- }
-
- </script>
- <script nonce='noncynonce'>
- var t_alert = async_test('Expecting alerts: ["PASS (1/2)","PASS (2/2)"]');
- var expected_alerts = ["PASS (1/2)", "PASS (2/2)"];
-
- function alert_assert(msg) {
- t_alert.step(function() {
- if (msg.match(/^FAIL/i)) {
- assert_unreached(msg);
- t_alert.done();
- }
- for (var i = 0; i < expected_alerts.length; i++) {
- if (expected_alerts[i] == msg) {
- assert_true(expected_alerts[i] == msg);
- expected_alerts.splice(i, 1);
- if (expected_alerts.length == 0) {
- t_alert.done();
- }
- return;
- }
- }
- assert_unreached('unexpected alert: ' + msg);
- t_log.done();
- });
- }
-
- </script>
+ <script src='../support/alertAssert.sub.js?alerts=["PASS (closely-quoted nonce)","PASS (nonce w/whitespace)"]'></script>
<!-- enforcing policy:
script-src 'self' 'unsafe-inline' 'nonce-noncynonce'; connect-src 'self';
-->
<script nonce="noncynonce">
- alert_assert('PASS (1/2)');
+ alert_assert('PASS (closely-quoted nonce)');
</script>
<script nonce=" noncynonce ">
- alert_assert('PASS (2/2)');
+ alert_assert('PASS (nonce w/whitespace)');
</script>
<script nonce="noncynonce noncynonce">
diff --git a/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/stylehash-allowed.sub.html b/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/stylehash-allowed.sub.html
index be7ef1a8198..282b1850257 100644
--- a/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/stylehash-allowed.sub.html
+++ b/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/stylehash-allowed.sub.html
@@ -34,7 +34,7 @@
</script>
<!-- enforcing policy:
-style-src 'sha1-eYyYGmKWdhpUewohaXk9o8IaLSw=' 'sha256-hndjYvzUzy2Ykuad81Cwsl1FOXX/qYs/aDVyUyNZwBw=' 'sha384-bSVm1i3sjPBRM4TwZtYTDjk9JxZMExYHWbFmP1SxDhJH4ue0Wu9OPOkY5hcqRcSt' 'sha512-440MmBLtj9Kp5Bqloogn9BqGDylY8vFsv5/zXL1zH2fJVssCoskRig4gyM+9KqwvCSapSz5CVoUGHQcxv43UQg=='; script-src 'self' 'unsafe-inline'; connect-src 'self';
+style-src 'sha256-pAKi9r4/WB7fHydbE3F3t8i8602ij2JN8zHJpL2T5BM=' 'sha256-hndjYvzUzy2Ykuad81Cwsl1FOXX/qYs/aDVyUyNZwBw=' 'sha384-bSVm1i3sjPBRM4TwZtYTDjk9JxZMExYHWbFmP1SxDhJH4ue0Wu9OPOkY5hcqRcSt' 'sha512-440MmBLtj9Kp5Bqloogn9BqGDylY8vFsv5/zXL1zH2fJVssCoskRig4gyM+9KqwvCSapSz5CVoUGHQcxv43UQg=='; script-src 'self' 'unsafe-inline'; connect-src 'self';
-->
</head>
diff --git a/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/stylehash-allowed.sub.html.sub.headers b/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/stylehash-allowed.sub.html.sub.headers
index 3f0aff7db89..2b519e85ec2 100644
--- a/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/stylehash-allowed.sub.html.sub.headers
+++ b/tests/wpt/web-platform-tests/content-security-policy/blink-contrib-2/stylehash-allowed.sub.html.sub.headers
@@ -3,4 +3,4 @@ Cache-Control: no-store, no-cache, must-revalidate
Cache-Control: post-check=0, pre-check=0, false
Pragma: no-cache
Set-Cookie: stylehash-allowed={{$id:uuid()}}; Path=/content-security-policy/blink-contrib-2
-Content-Security-Policy: style-src 'self' 'sha1-eYyYGmKWdhpUewohaXk9o8IaLSw=' 'sha256-hndjYvzUzy2Ykuad81Cwsl1FOXX/qYs/aDVyUyNZwBw=' 'sha384-bSVm1i3sjPBRM4TwZtYTDjk9JxZMExYHWbFmP1SxDhJH4ue0Wu9OPOkY5hcqRcSt' 'sha512-440MmBLtj9Kp5Bqloogn9BqGDylY8vFsv5/zXL1zH2fJVssCoskRig4gyM+9KqwvCSapSz5CVoUGHQcxv43UQg=='; script-src 'self' 'unsafe-inline'; connect-src 'self'; report-uri /content-security-policy/support/report.py?op=put&reportID={{$id}}
+Content-Security-Policy: style-src 'self' 'sha256-pAKi9r4/WB7fHydbE3F3t8i8602ij2JN8zHJpL2T5BM=' 'sha256-hndjYvzUzy2Ykuad81Cwsl1FOXX/qYs/aDVyUyNZwBw=' 'sha384-bSVm1i3sjPBRM4TwZtYTDjk9JxZMExYHWbFmP1SxDhJH4ue0Wu9OPOkY5hcqRcSt' 'sha512-440MmBLtj9Kp5Bqloogn9BqGDylY8vFsv5/zXL1zH2fJVssCoskRig4gyM+9KqwvCSapSz5CVoUGHQcxv43UQg=='; script-src 'self' 'unsafe-inline'; connect-src 'self'; report-uri /content-security-policy/support/report.py?op=put&reportID={{$id}}
diff --git a/tests/wpt/web-platform-tests/content-security-policy/blink-contrib/connect-src-beacon-allowed.sub.html b/tests/wpt/web-platform-tests/content-security-policy/blink-contrib/connect-src-beacon-allowed.sub.html
index 0562e0fd547..2beb00d020c 100644
--- a/tests/wpt/web-platform-tests/content-security-policy/blink-contrib/connect-src-beacon-allowed.sub.html
+++ b/tests/wpt/web-platform-tests/content-security-policy/blink-contrib/connect-src-beacon-allowed.sub.html
@@ -15,16 +15,27 @@ connect-src 'self' http://{{host}}:{{ports[http][0]}}; script-src 'self' 'unsafe
<body>
<script>
- try {
- var es = navigator.sendBeacon("http://{{host}}:{{ports[http][0]}}/cors/resources/status.py");
- log("Pass");
- } catch (e) {
- log("Fail");
- }
+ if (typeof navigator.sendBeacon != 'function') {
+ t_log.set_status(t_log.NOTRUN, "No navigator.sendBeacon, cannot run test.");
+ t_log.phase = t_log.phases.HAS_RESULT;
+ t_log.done();
+ } else {
+ try {
+ var es = navigator.sendBeacon("http://{{host}}:{{ports[http][0]}}/cors/resources/status.py");
+ log("Pass");
+ } catch (e) {
+ log("Fail");
+ }
+ var report = document.createElement("script");
+ report.src = "../support/checkReport.sub.js?reportExists=false";
+ report.async = true;
+ report.defer = true;
+ document.body.appendChild(report);
+
+ }
</script>
<div id="log"></div>
- <script async defer src="../support/checkReport.sub.js?reportExists=false"></script>
</body>
</html>
diff --git a/tests/wpt/web-platform-tests/content-security-policy/blink-contrib/connect-src-beacon-blocked.sub.html b/tests/wpt/web-platform-tests/content-security-policy/blink-contrib/connect-src-beacon-blocked.sub.html
index c459790d88a..fdde9e760b2 100644
--- a/tests/wpt/web-platform-tests/content-security-policy/blink-contrib/connect-src-beacon-blocked.sub.html
+++ b/tests/wpt/web-platform-tests/content-security-policy/blink-contrib/connect-src-beacon-blocked.sub.html
@@ -15,16 +15,26 @@ connect-src 'self' http://{{host}}:{{ports[http][0]}}; script-src 'self' 'unsafe
<body>
<script>
- try {
- var es = navigator.sendBeacon("http://www1.{{host}}:{{ports[http][0]}}/security/contentSecurityPolicy/echo-report.php");
- log("Fail");
- } catch (e) {
- log("Pass");
- }
+ if (typeof navigator.sendBeacon != 'function') {
+ t_log.set_status(t_log.NOTRUN, "No navigator.sendBeacon, cannot run test.");
+ t_log.phase = t_log.phases.HAS_RESULT;
+ t_log.done();
+ } else {
+ try {
+ var es = navigator.sendBeacon("http://www1.{{host}}:{{ports[http][0]}}/security/contentSecurityPolicy/echo-report.php");
+ log("Fail");
+ } catch (e) {
+ log("Pass");
+ }
+ var report = document.createElement("script");
+ report.src = "../support/checkReport.sub.js?reportExists=true&amp;reportField=violated-directive&amp;reportValue=connect-src%20&apos;self&apos;";
+ report.async = true;
+ report.defer = true;
+ document.body.appendChild(report);
+ }
</script>
<div id="log"></div>
- <script async defer src="../support/checkReport.sub.js?reportExists=true&amp;reportField=violated-directive&amp;reportValue=connect-src%20&apos;self&apos;"></script>
</body>
</html>
diff --git a/tests/wpt/web-platform-tests/content-security-policy/blink-contrib/connect-src-beacon-redirect-to-blocked.sub.html b/tests/wpt/web-platform-tests/content-security-policy/blink-contrib/connect-src-beacon-redirect-to-blocked.sub.html
index b60487bcef5..3d03100e366 100644
--- a/tests/wpt/web-platform-tests/content-security-policy/blink-contrib/connect-src-beacon-redirect-to-blocked.sub.html
+++ b/tests/wpt/web-platform-tests/content-security-policy/blink-contrib/connect-src-beacon-redirect-to-blocked.sub.html
@@ -18,13 +18,24 @@ connect-src 'self'; script-src 'self' 'unsafe-inline';
<p>The beacon should not follow the redirect to http://www1.{{host}}:{{ports[http][0]}}/content-security-policy/support/fail.png and send a CSP violation report.</p>
<p>Verify that a CSP connect-src directive blocks redirects.</p>
<script>
- navigator.sendBeacon(
- "/common/redirect.py?location=http://www1.{{host}}:{{ports[http][0]}}/content-security-policy/support/fail.png",
- "ping");
+ if (typeof navigator.sendBeacon != 'function') {
+ var t = async_test();
+ t.set_status(t.NOTRUN, "No navigator.sendBeacon, cannot run test.");
+ t.phase = t.phases.HAS_RESULT;
+ t.done();
+ } else {
+ navigator.sendBeacon(
+ "/common/redirect.py?location=http://www1.{{host}}:{{ports[http][0]}}/content-security-policy/support/fail.png",
+ "ping");
+ var report = document.createElement("script");
+ report.src = "../support/checkReport.sub.js?reportExists=true&amp;reportField=violated-directive&amp;reportValue=connect-src%20&apos;self&apos;";
+ report.async = true;
+ report.defer = true;
+ document.body.appendChild(report);
+ }
</script>
<div id="log"></div>
- <script async defer src="../support/checkReport.sub.js?reportExists=true&amp;reportField=violated-directive&amp;reportValue=connect-src%20&apos;self&apos;"></script>
</body>
</html>
diff --git a/tests/wpt/web-platform-tests/content-security-policy/blink-contrib/resources/worker-importscripts.js b/tests/wpt/web-platform-tests/content-security-policy/blink-contrib/resources/worker-importscripts.js
index ca9f2eca48e..65ec6f44624 100644
--- a/tests/wpt/web-platform-tests/content-security-policy/blink-contrib/resources/worker-importscripts.js
+++ b/tests/wpt/web-platform-tests/content-security-policy/blink-contrib/resources/worker-importscripts.js
@@ -2,5 +2,5 @@ try {
importScripts("/content-security-policy/blink-contrib/resources/post-message.js");
postMessage("importScripts allowed");
} catch (e) {
- postMessage("importScripts blocked: " + e);
+ postMessage("importScripts blocked");
}
diff --git a/tests/wpt/web-platform-tests/content-security-policy/blink-contrib/shared-worker-connect-src-allowed.sub.html b/tests/wpt/web-platform-tests/content-security-policy/blink-contrib/shared-worker-connect-src-allowed.sub.html
index 007d66c1fcb..17da111a84c 100644
--- a/tests/wpt/web-platform-tests/content-security-policy/blink-contrib/shared-worker-connect-src-allowed.sub.html
+++ b/tests/wpt/web-platform-tests/content-security-policy/blink-contrib/shared-worker-connect-src-allowed.sub.html
@@ -16,6 +16,11 @@ connect-src 'self' http://{{host}}:{{ports[http][0]}}; script-src 'self' 'unsafe
<body>
<script>
+ if(typeof SharedWorker != 'function') {
+ t_alert.set_status(t_alert.NOTRUN, "No SharedWorker, cannot run test.");
+ t_alert.phase = t_alert.phases.HAS_RESULT;
+ t_alert.done();
+ } else {
try {
var worker = new SharedWorker('http://{{host}}:{{ports[http][0]}}/content-security-policy/blink-contrib/resources/shared-worker-make-xhr-allowed.sub.js');
worker.port.onmessage = function(event) {
@@ -24,10 +29,15 @@ connect-src 'self' http://{{host}}:{{ports[http][0]}}; script-src 'self' 'unsafe
} catch (e) {
alert_assert(e);
}
+ var report = document.createElement("script");
+ report.src = "../support/checkReport.sub.js?reportExists=false";
+ report.async = true;
+ report.defer = true;
+ document.body.appendChild(report);
+ }
</script>
<div id="log"></div>
- <script async defer src="../support/checkReport.sub.js?reportExists=false"></script>
</body>
</html>
diff --git a/tests/wpt/web-platform-tests/content-security-policy/blink-contrib/shared-worker-connect-src-blocked.sub.html b/tests/wpt/web-platform-tests/content-security-policy/blink-contrib/shared-worker-connect-src-blocked.sub.html
index f049b933632..63225bf275e 100644
--- a/tests/wpt/web-platform-tests/content-security-policy/blink-contrib/shared-worker-connect-src-blocked.sub.html
+++ b/tests/wpt/web-platform-tests/content-security-policy/blink-contrib/shared-worker-connect-src-blocked.sub.html
@@ -22,6 +22,11 @@ connect-src *; script-src 'self' 'unsafe-inline';
should be sent since the worker's policy doesn't specify
a report-uri.</p>
<script>
+ if(typeof SharedWorker != 'function') {
+ t_alert.set_status(t_alert.NOTRUN, "No SharedWorker, cannot run test.");
+ t_alert.phase = t_alert.phases.HAS_RESULT;
+ t_alert.done();
+ } else {
try {
var worker = new SharedWorker('http://{{host}}:{{ports[http][0]}}/content-security-policy/blink-contrib/resources/shared-worker-make-xhr-blocked.sub.js');
worker.port.onmessage = function(event) {
@@ -30,10 +35,16 @@ connect-src *; script-src 'self' 'unsafe-inline';
} catch (e) {
alert_assert(e);
}
+ var report = document.createElement("script");
+ report.src = "../support/checkReport.sub.js?reportExists=false";
+ report.async = true;
+ report.defer = true;
+ document.body.appendChild(report);
+ }
+
</script>
<div id="log"></div>
- <script async defer src="../support/checkReport.sub.js?reportExists=false"></script>
</body>
</html>
diff --git a/tests/wpt/web-platform-tests/content-security-policy/blink-contrib/worker-importscripts-blocked.sub.html b/tests/wpt/web-platform-tests/content-security-policy/blink-contrib/worker-importscripts-blocked.sub.html
index d3240e385de..9ec49c03025 100644
--- a/tests/wpt/web-platform-tests/content-security-policy/blink-contrib/worker-importscripts-blocked.sub.html
+++ b/tests/wpt/web-platform-tests/content-security-policy/blink-contrib/worker-importscripts-blocked.sub.html
@@ -23,7 +23,7 @@ script-src 'self' 'unsafe-inline' 'unsafe-eval' 'unsafe-inline' 127.0.0.1:8000;
worker.onmessage = function(event) {
result = event.data;
test(function() {
- assert_equals(result, 'importScripts blocked: NetworkError: Failed to execute \'importScripts\' on \'WorkerGlobalScope\': The script at \'http://{{host}}:{{ports[http][0]}}/content-security-policy/blink-contrib/resources/post-message.js\' failed to load.')
+ assert_equals(result, 'importScripts blocked')
});
log("TEST COMPLETE");
};
diff --git a/tests/wpt/web-platform-tests/content-security-policy/child-src/child-src-worker-blocked.sub.html b/tests/wpt/web-platform-tests/content-security-policy/child-src/child-src-worker-blocked.sub.html
index d8908b17b3d..8ed6b157a81 100644
--- a/tests/wpt/web-platform-tests/content-security-policy/child-src/child-src-worker-blocked.sub.html
+++ b/tests/wpt/web-platform-tests/content-security-policy/child-src/child-src-worker-blocked.sub.html
@@ -17,6 +17,10 @@ child-src 'none'; script-src 'self' 'unsafe-inline' 'unsafe-inline'; connect-src
<script>
try {
var foo = new Worker('http://{{host}}:{{ports[http][0]}}/content-security-policy/blink-contrib/resources/post-message.js');
+ foo.onerror = function(event) {
+ event.preventDefault();
+ alert_assert("PASS");
+ }
foo.onmessage = function(event) {
alert_assert("FAIL");
};
diff --git a/tests/wpt/web-platform-tests/content-security-policy/media-src/media-src-7_3_2.html b/tests/wpt/web-platform-tests/content-security-policy/media-src/media-src-7_3_2.html
index c93af3b80c1..597ac7f8fa7 100644
--- a/tests/wpt/web-platform-tests/content-security-policy/media-src/media-src-7_3_2.html
+++ b/tests/wpt/web-platform-tests/content-security-policy/media-src/media-src-7_3_2.html
@@ -52,10 +52,17 @@
source_test.step(function() {
source_test.set_status(source_test.FAIL);
});
+
+ setTimeout(function() {
+ if(source_test.phase != source_test.phases.COMPLETE) {
+ source_test.step( function () { assert_unreached("Onerror event never fired for track element."); });
+ source_test.done();
+ }
+ }, 2 * 1000);
</script>
<script async defer src="../support/checkReport.sub.js?reportField=violated-directive&reportValue=media-src%20%27self%27">
</script>
</body>
-</html> \ No newline at end of file
+</html>
diff --git a/tests/wpt/web-platform-tests/content-security-policy/media-src/media-src-redir-bug.sub.html b/tests/wpt/web-platform-tests/content-security-policy/media-src/media-src-redir-bug.sub.html
index f12f8ffc56f..b8351193041 100644
--- a/tests/wpt/web-platform-tests/content-security-policy/media-src/media-src-redir-bug.sub.html
+++ b/tests/wpt/web-platform-tests/content-security-policy/media-src/media-src-redir-bug.sub.html
@@ -55,8 +55,8 @@
</video>
<video id="videoObject2" width="320" height="240" controls
- onerror="media_error_handler(src_test)"
- onloadeddata="media_loaded(src_test)"
+ onerror="media_error_handler(src_redir_test)"
+ onloadeddata="media_loaded(src_redir_test)"
src="/common/redirect.py?location=http://www2.{{host}}:{{ports[http][0]}}/media/white.mp4">
<script async defer src="../support/checkReport.sub.js?reportExists=false">
diff --git a/tests/wpt/web-platform-tests/content-security-policy/support/alertAssert.sub.js b/tests/wpt/web-platform-tests/content-security-policy/support/alertAssert.sub.js
index 6ca2849ca31..607d0d4212c 100644
--- a/tests/wpt/web-platform-tests/content-security-policy/support/alertAssert.sub.js
+++ b/tests/wpt/web-platform-tests/content-security-policy/support/alertAssert.sub.js
@@ -1,5 +1,9 @@
// note, this template substitution is XSS, but no way to avoid it in this framework
var expected_alerts = {{GET[alerts]}};
+var timeout= "{{GET[timeout]}}";
+if (timeout == "") {
+ timeout = 2;
+}
if(expected_alerts.length == 0) {
function alert_assert(msg) {
@@ -7,7 +11,13 @@ if(expected_alerts.length == 0) {
}
} else {
var t_alert = async_test('Expecting alerts: {{GET[alerts]}}');
- function alert_assert(msg) {
+ setTimeout(function() {
+ if(t_alert.phase != t_alert.phases.COMPLETE) {
+ t_alert.step(function() { assert_unreached('Alert timeout, expected alerts ' + expected_alerts + ' not fired.') });
+ t_alert.done();
+ }
+ }, timeout * 100);
+ var alert_assert = function (msg) {
t_alert.step(function () {
if(msg && msg instanceof Error) {
msg = msg.message;
@@ -29,5 +39,5 @@ if(expected_alerts.length == 0) {
assert_unreached('unexpected alert: ' + msg);
t_log.done();
});
- }
+ }.bind(this);
}
diff --git a/tests/wpt/web-platform-tests/content-security-policy/support/logTest.sub.js b/tests/wpt/web-platform-tests/content-security-policy/support/logTest.sub.js
index d797475d2a6..6bbdb43f72d 100644
--- a/tests/wpt/web-platform-tests/content-security-policy/support/logTest.sub.js
+++ b/tests/wpt/web-platform-tests/content-security-policy/support/logTest.sub.js
@@ -1,5 +1,9 @@
// note, this template substitution is XSS, but no way to avoid it in this framework
var expected_logs = {{GET[logs]}};
+var timeout = "{{GET[timeout]}}";
+if (timeout == "") {
+ timeout = 2;
+}
if (expected_logs.length == 0) {
function log_assert(msg) {
@@ -7,6 +11,12 @@ if (expected_logs.length == 0) {
}
} else {
var t_log = async_test('Expecting logs: {{GET[logs]}}');
+ setTimeout(function() {
+ if(t_log.phase != t_log.phases.COMPLETE){
+ t_log.step(function () { assert_unreached('Logging timeout, expected logs ' + expected_logs + ' not sent.') });
+ t_log.done();
+ }
+ }, timeout * 1000);
function log(msg) {
//cons/**/ole.log(msg);
t_log.step(function () {
diff --git a/tests/wpt/web-platform-tests/dom/events/Event-defaultPrevented-after-dispatch.html b/tests/wpt/web-platform-tests/dom/events/Event-defaultPrevented-after-dispatch.html
new file mode 100644
index 00000000000..decf7e9927f
--- /dev/null
+++ b/tests/wpt/web-platform-tests/dom/events/Event-defaultPrevented-after-dispatch.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Event.defaultPrevented is not reset after dipatchEvent()</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<div id=log></div>
+<input id="target" type="hidden" value=""/>
+<script>
+test(function() {
+ var EVENT = "foo";
+ var TARGET = document.getElementById("target");
+ var evt = document.createEvent("Event");
+ evt.initEvent(EVENT, true, true);
+
+ TARGET.addEventListener(EVENT, this.step_func(function(e) {
+ e.preventDefault();
+ assert_true(e.defaultPrevented, "during dispatch");
+ }), true);
+ TARGET.dispatchEvent(evt);
+
+ assert_true(evt.defaultPrevented, "after dispatch");
+ assert_equals(evt.target, TARGET);
+});
+</script>
diff --git a/tests/wpt/web-platform-tests/html/OWNERS b/tests/wpt/web-platform-tests/html/OWNERS
index 1419ab7b547..6503090a56f 100644
--- a/tests/wpt/web-platform-tests/html/OWNERS
+++ b/tests/wpt/web-platform-tests/html/OWNERS
@@ -1,3 +1,4 @@
+@ayg
@Ms2ger
@foolip
@gsnedders
diff --git a/tests/wpt/web-platform-tests/html/semantics/embedded-content/the-embed-element/embed-ignored-in-media-element.html b/tests/wpt/web-platform-tests/html/semantics/embedded-content/the-embed-element/embed-ignored-in-media-element.html
new file mode 100644
index 00000000000..d29d520f0e5
--- /dev/null
+++ b/tests/wpt/web-platform-tests/html/semantics/embedded-content/the-embed-element/embed-ignored-in-media-element.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>HTML Test: The embed element represents a document</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<meta name="assert" content="Check if the embed element is ignored when used inside a media element">
+<script type="application/javascript">
+ window.childLoaded = false;
+ async_test(function() {
+ addEventListener("load", this.step_func_done(function() {
+ assert_false(window.childLoaded);
+ }));
+ }, "Test embed being ignored inside media element");
+</script>
+<body>
+ <video>
+ <embed type="text/html" src="embed-iframe.html" />
+ </video>
+ <audio>
+ <embed type="text/html" src="embed-iframe.html" />
+ </audio>
+</body>
diff --git a/tests/wpt/web-platform-tests/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-1.html b/tests/wpt/web-platform-tests/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-1.html
new file mode 100644
index 00000000000..65a1a02b11e
--- /dev/null
+++ b/tests/wpt/web-platform-tests/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-1.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>
+ When a listener from window A is added to an event target in window B via the
+ addEventListener function from window B, errors in that listener should be
+ reported to window A.
+</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<iframe></iframe>
+<iframe></iframe>
+<script>
+test(function() {
+ var f = new frames[0].Function("thereIsNoSuchCallable()");
+ frames[1].document.addEventListener("myevent", f);
+ var frame0ErrorFired = false;
+ var frame1ErrorFired = false;
+ var ourErrorFired = false;
+ frames[0].addEventListener("error", function() {
+ frame0ErrorFired = true;
+ });
+ frames[1].addEventListener("error", function() {
+ frame1ErrorFired = true;
+ });
+ addEventListener("error", function() {
+ ourErrorFired = true;
+ });
+ frames[1].document.dispatchEvent(new Event("myevent"));
+ assert_true(frame0ErrorFired);
+ assert_false(frame1ErrorFired);
+ assert_false(ourErrorFired);
+}, "The error event from an event listener should fire on that listener's global");
+</script>
diff --git a/tests/wpt/web-platform-tests/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-2.html b/tests/wpt/web-platform-tests/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-2.html
new file mode 100644
index 00000000000..6c5476542b8
--- /dev/null
+++ b/tests/wpt/web-platform-tests/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-2.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>
+ When a listener from window A is added to an event target in window B via the
+ addEventListener function from window A, errors in that listener should be
+ reported to window A.
+</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<iframe></iframe>
+<iframe></iframe>
+<script>
+test(function() {
+ var f = new frames[0].Function("thereIsNoSuchCallable()");
+ frames[0].document.addEventListener.call(frames[1].document, "myevent", f);
+ var frame0ErrorFired = false;
+ var frame1ErrorFired = false;
+ var ourErrorFired = false;
+ frames[0].addEventListener("error", function() {
+ frame0ErrorFired = true;
+ });
+ frames[1].addEventListener("error", function() {
+ frame1ErrorFired = true;
+ });
+ addEventListener("error", function() {
+ ourErrorFired = true;
+ });
+ frames[1].document.dispatchEvent(new Event("myevent"));
+ assert_true(frame0ErrorFired);
+ assert_false(frame1ErrorFired);
+ assert_false(ourErrorFired);
+}, "The error event from an event listener should fire on that listener's global");
+</script>
diff --git a/tests/wpt/web-platform-tests/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-3.html b/tests/wpt/web-platform-tests/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-3.html
new file mode 100644
index 00000000000..5e78baa8de0
--- /dev/null
+++ b/tests/wpt/web-platform-tests/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-3.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>
+ When a listener from window A is added to an event target in window A via the
+ addEventListener function from window A, errors in that listener should be
+ reported to window A.
+</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<iframe></iframe>
+<iframe></iframe>
+<script>
+test(function() {
+ var f = new frames[1].Function("thereIsNoSuchCallable()");
+ frames[1].document.addEventListener("myevent", f);
+ var frame0ErrorFired = false;
+ var frame1ErrorFired = false;
+ var ourErrorFired = false;
+ frames[0].addEventListener("error", function() {
+ frame0ErrorFired = true;
+ });
+ frames[1].addEventListener("error", function() {
+ frame1ErrorFired = true;
+ });
+ addEventListener("error", function() {
+ ourErrorFired = true;
+ });
+ frames[1].document.dispatchEvent(new Event("myevent"));
+ assert_false(frame0ErrorFired);
+ assert_true(frame1ErrorFired);
+ assert_false(ourErrorFired);
+}, "The error event from an event listener should fire on that listener's global");
+</script>
diff --git a/tests/wpt/web-platform-tests/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-4.html b/tests/wpt/web-platform-tests/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-4.html
new file mode 100644
index 00000000000..a5f35d613f7
--- /dev/null
+++ b/tests/wpt/web-platform-tests/html/webappapis/scripting/processing-model-2/window-onerror-with-cross-frame-event-listeners-4.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>
+ When a listener from window A is added to an event target in window A via the
+ addEventListener function from window B, errors in that listener should be
+ reported to window A.
+</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<iframe></iframe>
+<iframe></iframe>
+<script>
+test(function() {
+ var f = new frames[1].Function("thereIsNoSuchCallable()");
+ frames[0].document.addEventListener.call(frames[1].document, "myevent", f);
+ var frame0ErrorFired = false;
+ var frame1ErrorFired = false;
+ var ourErrorFired = false;
+ frames[0].addEventListener("error", function() {
+ frame0ErrorFired = true;
+ });
+ frames[1].addEventListener("error", function() {
+ frame1ErrorFired = true;
+ });
+ addEventListener("error", function() {
+ ourErrorFired = true;
+ });
+ frames[1].document.dispatchEvent(new Event("myevent"));
+ assert_false(frame0ErrorFired);
+ assert_true(frame1ErrorFired);
+ assert_false(ourErrorFired);
+}, "The error event from an event listener should fire on that listener's global");
+</script>
diff --git a/tests/wpt/web-platform-tests/media-source/OWNERS b/tests/wpt/web-platform-tests/media-source/OWNERS
index fa70c6cc1d2..aefaf66dab0 100644
--- a/tests/wpt/web-platform-tests/media-source/OWNERS
+++ b/tests/wpt/web-platform-tests/media-source/OWNERS
@@ -3,3 +3,4 @@
@foolip
@shishimaru
@sideshowbarker
+@wolenetz
diff --git a/tests/wpt/web-platform-tests/resource-timing/test_resource_timing.js b/tests/wpt/web-platform-tests/resource-timing/test_resource_timing.js
index 2862e16d100..60c8c88f548 100644
--- a/tests/wpt/web-platform-tests/resource-timing/test_resource_timing.js
+++ b/tests/wpt/web-platform-tests/resource-timing/test_resource_timing.js
@@ -161,6 +161,13 @@ function resource_load(expected)
t["timing_attrs"].step(function test() {
var actual = window.performance.getEntriesByName(expected.name)[0];
+
+ // Debugging bug 1263428
+ // Feel free to remove/overwrite this piece of code
+ if (actual.connectStart < actual.domainLookupEnd) {
+ assert_true(false, "actual: "+JSON.stringify(actual));
+ }
+
assert_equals(actual.redirectStart, 0, "redirectStart time");
assert_equals(actual.redirectEnd, 0, "redirectEnd time");
assert_true(actual.secureConnectionStart == undefined ||
diff --git a/tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-add.https.html b/tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-add.https.html
index 57e74b750f7..b353ae02269 100644
--- a/tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-add.https.html
+++ b/tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-add.https.html
@@ -4,7 +4,7 @@
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../service-workers/resources/test-helpers.js"></script>
+<script src="../../service-worker/resources/test-helpers.sub.js"></script>
<script>
service_worker_test('../script-tests/cache-add.js');
</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-delete.https.html b/tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-delete.https.html
index 7a5a43fd9e4..81da300020c 100644
--- a/tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-delete.https.html
+++ b/tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-delete.https.html
@@ -4,7 +4,7 @@
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../service-workers/resources/test-helpers.js"></script>
+<script src="../../service-worker/resources/test-helpers.sub.js"></script>
<script>
service_worker_test('../script-tests/cache-delete.js');
</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-match.https.html b/tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-match.https.html
index 6126568fb46..59ef34bb7b9 100644
--- a/tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-match.https.html
+++ b/tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-match.https.html
@@ -4,7 +4,7 @@
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../service-workers/resources/test-helpers.js"></script>
+<script src="../../service-worker/resources/test-helpers.sub.js"></script>
<script>
service_worker_test('../script-tests/cache-match.js');
</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-matchAll.https.html b/tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-matchAll.https.html
index 878fe1209f3..a2aa1f242e7 100644
--- a/tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-matchAll.https.html
+++ b/tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-matchAll.https.html
@@ -4,7 +4,7 @@
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../service-workers/resources/test-helpers.js"></script>
+<script src="../../service-worker/resources/test-helpers.sub.js"></script>
<script>
service_worker_test('../script-tests/cache-matchAll.js');
</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-put.https.html b/tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-put.https.html
index d67f9391a75..9602e3bfcb4 100644
--- a/tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-put.https.html
+++ b/tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-put.https.html
@@ -4,7 +4,7 @@
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../service-workers/resources/test-helpers.js"></script>
+<script src="../../service-worker/resources/test-helpers.sub.js"></script>
<script>
service_worker_test('../script-tests/cache-put.js');
</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-storage-keys.https.html b/tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-storage-keys.https.html
index ec7e14b7af3..1d1005dccc7 100644
--- a/tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-storage-keys.https.html
+++ b/tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-storage-keys.https.html
@@ -4,7 +4,7 @@
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../service-workers/resources/test-helpers.js"></script>
+<script src="../../service-worker/resources/test-helpers.sub.js"></script>
<script>
service_worker_test('../script-tests/cache-storage-keys.js');
</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-storage-match.https.html b/tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-storage-match.https.html
index 937f143ebb0..6c4b72885fd 100644
--- a/tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-storage-match.https.html
+++ b/tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-storage-match.https.html
@@ -4,7 +4,7 @@
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../service-workers/resources/test-helpers.js"></script>
+<script src="../../service-worker/resources/test-helpers.sub.js"></script>
<script>
service_worker_test('../script-tests/cache-storage-match.js');
</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-storage.https.html b/tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-storage.https.html
index 62c6b63572c..5e240a3b699 100644
--- a/tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-storage.https.html
+++ b/tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/cache-storage.https.html
@@ -4,7 +4,7 @@
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../service-workers/resources/test-helpers.js"></script>
+<script src="../../service-worker/resources/test-helpers.sub.js"></script>
<script>
service_worker_test('../script-tests/cache-storage.js');
</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/credentials.html b/tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/credentials.html
index f2d8838f2a6..116fd9ca904 100644
--- a/tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/credentials.html
+++ b/tests/wpt/web-platform-tests/service-workers/cache-storage/serviceworker/credentials.html
@@ -4,7 +4,7 @@
<link rel="help" href="https://slightlyoff.github.io/ServiceWorker/spec/service_worker/#cache-storage">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../service-workers/resources/test-helpers.js"></script>
+<script src="../../service-worker/resources/test-helpers.sub.js"></script>
<style>iframe { display: none; }</style>
<script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-event.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-event.https.html
index 9869f3b2799..4d7e9a4da1b 100644
--- a/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-event.https.html
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-event.https.html
@@ -440,8 +440,9 @@ async_test(function(t) {
.then(function() { return with_iframe(scope); })
.then(function(f) {
frame = f;
+ assert_equals(frame.contentWindow.document.body.textContent, 'default');
var tests = cacheTypes.map(function(type) {
- return new Promise(function(resolve) {
+ return new Promise(function(resolve, reject) {
return frame.contentWindow.fetch(scope + '=' + type,
{cache: type})
.then(function(response) { return response.text(); })
@@ -450,10 +451,25 @@ async_test(function(t) {
assert_equals(response_text, expected,
'Service Worker should respond to fetch with the correct type');
})
- .then(resolve);
+ .then(resolve)
+ .catch(reject);
});
});
- return Promise.all(tests);
+ })
+ .then(function() {
+ return new Promise(function(resolve, reject) {
+ frame.addEventListener('load', function onLoad() {
+ frame.removeEventListener('load', onLoad);
+ try {
+ assert_equals(frame.contentWindow.document.body.textContent,
+ 'no-cache');
+ resolve();
+ } catch (e) {
+ reject(e);
+ }
+ });
+ frame.contentWindow.location.reload();
+ });
})
.then(function() {
frame.remove();
@@ -462,5 +478,55 @@ async_test(function(t) {
.catch(unreached_rejection(t));
}, 'Service Worker responds to fetch event with the correct cache types');
+async_test(function(t) {
+ var scope = 'resources/simple.html?eventsource';
+ var frame;
+
+ function test_eventsource(opts) {
+ return new Promise(function(resolve, reject) {
+ var eventSource = new frame.contentWindow.EventSource(scope, opts);
+ eventSource.addEventListener('message', function(msg) {
+ eventSource.close();
+ try {
+ var data = JSON.parse(msg.data);
+ assert_equals(data.mode, 'cors',
+ 'EventSource should make CORS requests.');
+ assert_equals(data.cache, 'no-store',
+ 'EventSource should bypass the http cache.');
+ var expectedCredentials = opts.withCredentials ? 'include'
+ : 'same-origin';
+ assert_equals(data.credentials, expectedCredentials,
+ 'EventSource should pass correct credentials mode.');
+ resolve();
+ } catch (e) {
+ reject(e);
+ }
+ });
+ eventSource.addEventListener('error', function(e) {
+ eventSource.close();
+ reject('The EventSource fired an error event.');
+ });
+ });
+ }
+
+ service_worker_unregister_and_register(t, worker, scope)
+ .then(function(reg) {
+ return wait_for_state(t, reg.installing, 'activated');
+ })
+ .then(function() { return with_iframe(scope); })
+ .then(function(f) {
+ frame = f;
+ return test_eventsource({ withCredentials: false });
+ })
+ .then(function() {
+ return test_eventsource({ withCredentials: true });
+ })
+ .then(function() {
+ frame.remove();
+ return service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ }, 'Service Worker should intercept EventSource');
+
</script>
</body>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-event-test-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-event-test-worker.js
index 5180c30f7d4..44ea828c686 100644
--- a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-event-test-worker.js
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-event-test-worker.js
@@ -95,6 +95,22 @@ function handleCache(event) {
event.respondWith(new Response(event.request.cache));
}
+function handleEventSource(event) {
+ if (event.request.mode === 'navigate') {
+ return;
+ }
+ var data = {
+ mode: event.request.mode,
+ cache: event.request.cache,
+ credentials: event.request.credentials
+ };
+ var body = 'data:' + JSON.stringify(data) + '\n\n';
+ event.respondWith(new Response(body, {
+ headers: { 'Content-Type': 'text/event-stream' }
+ }
+ ));
+}
+
self.addEventListener('fetch', function(event) {
var url = event.request.url;
var handlers = [
@@ -112,6 +128,7 @@ self.addEventListener('fetch', function(event) {
{ pattern: '?used-check', fn: handleUsedCheck },
{ pattern: '?fragment-check', fn: handleFragmentCheck },
{ pattern: '?cache', fn: handleCache },
+ { pattern: '?eventsource', fn: handleEventSource },
];
var handler = null;
diff --git a/tests/wpt/web-platform-tests/service-workers/service-workers/resources/test-helpers.js b/tests/wpt/web-platform-tests/service-workers/service-workers/resources/test-helpers.js
deleted file mode 100644
index 147ea612c2f..00000000000
--- a/tests/wpt/web-platform-tests/service-workers/service-workers/resources/test-helpers.js
+++ /dev/null
@@ -1,222 +0,0 @@
-// Adapter for testharness.js-style tests with Service Workers
-
-function service_worker_unregister_and_register(test, url, scope) {
- if (!scope || scope.length == 0)
- return Promise.reject(new Error('tests must define a scope'));
-
- var options = { scope: scope };
- return service_worker_unregister(test, scope)
- .then(function() {
- return navigator.serviceWorker.register(url, options);
- })
- .catch(unreached_rejection(test,
- 'unregister and register should not fail'));
-}
-
-function service_worker_unregister(test, documentUrl) {
- return navigator.serviceWorker.getRegistration(documentUrl)
- .then(function(registration) {
- if (registration)
- return registration.unregister();
- })
- .catch(unreached_rejection(test, 'unregister should not fail'));
-}
-
-function service_worker_unregister_and_done(test, scope) {
- return service_worker_unregister(test, scope)
- .then(test.done.bind(test));
-}
-
-function unreached_fulfillment(test, prefix) {
- return test.step_func(function(result) {
- var error_prefix = prefix || 'unexpected fulfillment';
- assert_unreached(error_prefix + ': ' + result);
- });
-}
-
-// Rejection-specific helper that provides more details
-function unreached_rejection(test, prefix) {
- return test.step_func(function(error) {
- var reason = error.message || error.name || error;
- var error_prefix = prefix || 'unexpected rejection';
- assert_unreached(error_prefix + ': ' + reason);
- });
-}
-
-// Adds an iframe to the document and returns a promise that resolves to the
-// iframe when it finishes loading. The caller is responsible for removing the
-// iframe later if needed.
-function with_iframe(url) {
- return new Promise(function(resolve) {
- var frame = document.createElement('iframe');
- frame.src = url;
- frame.onload = function() { resolve(frame); };
- document.body.appendChild(frame);
- });
-}
-
-function normalizeURL(url) {
- return new URL(url, self.location).toString().replace(/#.*$/, '');
-}
-
-function wait_for_update(test, registration) {
- if (!registration || registration.unregister == undefined) {
- return Promise.reject(new Error(
- 'wait_for_update must be passed a ServiceWorkerRegistration'));
- }
-
- return new Promise(test.step_func(function(resolve) {
- registration.addEventListener('updatefound', test.step_func(function() {
- resolve(registration.installing);
- }));
- }));
-}
-
-function wait_for_state(test, worker, state) {
- if (!worker || worker.state == undefined) {
- return Promise.reject(new Error(
- 'wait_for_state must be passed a ServiceWorker'));
- }
- if (worker.state === state)
- return Promise.resolve(state);
-
- if (state === 'installing') {
- switch (worker.state) {
- case 'installed':
- case 'activating':
- case 'activated':
- case 'redundant':
- return Promise.reject(new Error(
- 'worker is ' + worker.state + ' but waiting for ' + state));
- }
- }
-
- if (state === 'installed') {
- switch (worker.state) {
- case 'activating':
- case 'activated':
- case 'redundant':
- return Promise.reject(new Error(
- 'worker is ' + worker.state + ' but waiting for ' + state));
- }
- }
-
- if (state === 'activating') {
- switch (worker.state) {
- case 'activated':
- case 'redundant':
- return Promise.reject(new Error(
- 'worker is ' + worker.state + ' but waiting for ' + state));
- }
- }
-
- if (state === 'activated') {
- switch (worker.state) {
- case 'redundant':
- return Promise.reject(new Error(
- 'worker is ' + worker.state + ' but waiting for ' + state));
- }
- }
-
- return new Promise(test.step_func(function(resolve) {
- worker.addEventListener('statechange', test.step_func(function() {
- if (worker.state === state)
- resolve(state);
- }));
- }));
-}
-
-// Declare a test that runs entirely in the ServiceWorkerGlobalScope. The |url|
-// is the service worker script URL. This function:
-// - Instantiates a new test with the description specified in |description|.
-// The test will succeed if the specified service worker can be successfully
-// registered and installed.
-// - Creates a new ServiceWorker registration with a scope unique to the current
-// document URL. Note that this doesn't allow more than one
-// service_worker_test() to be run from the same document.
-// - Waits for the new worker to begin installing.
-// - Imports tests results from tests running inside the ServiceWorker.
-function service_worker_test(url, description) {
- // If the document URL is https://example.com/document and the script URL is
- // https://example.com/script/worker.js, then the scope would be
- // https://example.com/script/scope/document.
- var scope = new URL('scope' + window.location.pathname,
- new URL(url, window.location)).toString();
- promise_test(function(test) {
- return service_worker_unregister_and_register(test, url, scope)
- .then(function(registration) {
- add_completion_callback(function() {
- registration.unregister();
- });
- return wait_for_update(test, registration)
- .then(function(worker) {
- return fetch_tests_from_worker(worker);
- });
- });
- }, description);
-}
-
-function get_host_info() {
- var ORIGINAL_HOST = '127.0.0.1';
- var REMOTE_HOST = 'localhost';
- var UNAUTHENTICATED_HOST = 'example.test';
- var HTTP_PORT = 8000;
- var HTTPS_PORT = 8443;
- try {
- // In W3C test, we can get the hostname and port number in config.json
- // using wptserve's built-in pipe.
- // http://wptserve.readthedocs.org/en/latest/pipes.html#built-in-pipes
- HTTP_PORT = eval('{{ports[http][0]}}');
- HTTPS_PORT = eval('{{ports[https][0]}}');
- ORIGINAL_HOST = eval('\'{{host}}\'');
- REMOTE_HOST = 'www1.' + ORIGINAL_HOST;
- } catch (e) {
- }
- return {
- HTTP_ORIGIN: 'http://' + ORIGINAL_HOST + ':' + HTTP_PORT,
- HTTPS_ORIGIN: 'https://' + ORIGINAL_HOST + ':' + HTTPS_PORT,
- HTTP_REMOTE_ORIGIN: 'http://' + REMOTE_HOST + ':' + HTTP_PORT,
- HTTPS_REMOTE_ORIGIN: 'https://' + REMOTE_HOST + ':' + HTTPS_PORT,
- UNAUTHENTICATED_ORIGIN: 'http://' + UNAUTHENTICATED_HOST + ':' + HTTP_PORT
- };
-}
-
-function base_path() {
- return location.pathname.replace(/\/[^\/]*$/, '/');
-}
-
-function test_login(test, origin, username, password, cookie) {
- return new Promise(function(resolve, reject) {
- with_iframe(
- origin +
- '/serviceworker/resources/fetch-access-control-login.html')
- .then(test.step_func(function(frame) {
- var channel = new MessageChannel();
- channel.port1.onmessage = test.step_func(function() {
- frame.remove();
- resolve();
- });
- frame.contentWindow.postMessage(
- {username: username, password: password, cookie: cookie},
- origin, [channel.port2]);
- }));
- });
-}
-
-function login(test) {
- return test_login(test, 'http://127.0.0.1:8000',
- 'username1', 'password1', 'cookie1')
- .then(function() {
- return test_login(test, 'http://localhost:8000',
- 'username2', 'password2', 'cookie2');
- });
-}
-
-function login_https(test) {
- return test_login(test, 'https://127.0.0.1:8443',
- 'username1s', 'password1s', 'cookie1')
- .then(function() {
- return test_login(test, 'https://localhost:8443',
- 'username2s', 'password2s', 'cookie2');
- });
-}
diff --git a/tests/wpt/web-platform-tests/tools/manifest/manifest.py b/tests/wpt/web-platform-tests/tools/manifest/manifest.py
index 33e194df409..b154a488004 100644
--- a/tests/wpt/web-platform-tests/tools/manifest/manifest.py
+++ b/tests/wpt/web-platform-tests/tools/manifest/manifest.py
@@ -42,6 +42,9 @@ class Manifest(object):
for path in self.local_changes.iterdeleted():
if path in paths:
del paths[path]
+ if item_type == "reftest":
+ for path, items in self.local_changes.iterdeletedreftests():
+ paths[path] -= items
yield item_type, paths
@@ -170,14 +173,37 @@ class Manifest(object):
self.url_base = url_base
def update_reftests(self):
- reftest_nodes = self.reftest_nodes.copy()
- for path, items in self.local_changes.reftest_nodes.iteritems():
- reftest_nodes[path] |= items
+ default_reftests = self.compute_reftests(self.reftest_nodes)
+ all_reftest_nodes = self.reftest_nodes.copy()
+ all_reftest_nodes.update(self.local_changes.reftest_nodes)
- #TODO: remove locally deleted files
- tests = set()
- for items in reftest_nodes.values():
- tests |= set(item for item in items if not item.is_reference)
+ for item in self.local_changes.iterdeleted():
+ if item in all_reftest_nodes:
+ del all_reftest_nodes[item]
+
+ modified_reftests = self.compute_reftests(all_reftest_nodes)
+
+ added_reftests = modified_reftests - default_reftests
+ # The interesting case here is not when the file is deleted,
+ # but when a reftest like A == B is changed to the form
+ # C == A == B, so that A still exists but is now a ref rather than
+ # a test.
+ removed_reftests = default_reftests - modified_reftests
+
+ dests = [(default_reftests, self._data["reftest"]),
+ (added_reftests, self.local_changes._data["reftest"]),
+ (removed_reftests, self.local_changes._deleted_reftests)]
+
+ #TODO: Warn if there exist unreachable reftest nodes
+ for source, target in dests:
+ for item in source:
+ target[item.path].add(item)
+
+ def compute_reftests(self, reftest_nodes):
+ """Given a set of reftest_nodes, return a set of all the nodes that are top-level
+ tests i.e. don't have any incoming reference links."""
+
+ reftests = set()
has_inbound = set()
for path, items in reftest_nodes.iteritems():
@@ -185,18 +211,13 @@ class Manifest(object):
for ref_url, ref_type in item.references:
has_inbound.add(ref_url)
- if self.local_changes.reftest_nodes:
- target = self.local_changes
- else:
- target = self
-
- #TODO: Warn if there exist unreachable reftest nodes
-
for path, items in reftest_nodes.iteritems():
for item in items:
if item.url in has_inbound:
continue
- target._data["reftest"][path].add(item)
+ reftests.add(item)
+
+ return reftests
def to_json(self):
out_items = {
@@ -261,6 +282,7 @@ class Manifest(object):
source_files=source_files)
return self
+
class LocalChanges(object):
def __init__(self, manifest):
self.manifest = manifest
@@ -268,6 +290,7 @@ class LocalChanges(object):
self._deleted = set()
self.reftest_nodes = defaultdict(set)
self.reftest_nodes_by_url = {}
+ self._deleted_reftests = defaultdict(set)
def add(self, item):
if item is None:
@@ -305,6 +328,10 @@ class LocalChanges(object):
for item in self._deleted:
yield item
+ def iterdeletedreftests(self):
+ for item in self._deleted_reftests.iteritems():
+ yield item
+
def __getitem__(self, item_type):
return self._data[item_type]
@@ -312,9 +339,13 @@ class LocalChanges(object):
reftest_nodes = {from_os_path(key): [v.to_json() for v in value]
for key, value in self.reftest_nodes.iteritems()}
+ deleted_reftests = {from_os_path(key): [v.to_json() for v in value]
+ for key, value in self._deleted_reftests.iteritems()}
+
rv = {"items": defaultdict(dict),
"reftest_nodes": reftest_nodes,
- "deleted": [from_os_path(path) for path in self._deleted]}
+ "deleted": [from_os_path(path) for path in self._deleted],
+ "deleted_reftests": deleted_reftests}
for test_type, paths in self._data.iteritems():
for path, tests in paths.iteritems():
@@ -355,6 +386,13 @@ class LocalChanges(object):
for item in obj["deleted"]:
self.add_deleted(to_os_path(item))
+ for path, values in obj.get("deleted_reftests", {}).iteritems():
+ path = to_os_path(path)
+ for v in values:
+ item = RefTest.from_json(self.manifest, tests_root, v,
+ source_files=source_files)
+ self._deleted_reftests[path].add(item)
+
return self
def load(tests_root, manifest):
diff --git a/tests/wpt/web-platform-tests/tools/manifest/tests/__init__.py b/tests/wpt/web-platform-tests/tools/manifest/tests/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/manifest/tests/__init__.py
diff --git a/tests/wpt/web-platform-tests/tools/manifest/tests/test_manifest.py b/tests/wpt/web-platform-tests/tools/manifest/tests/test_manifest.py
new file mode 100644
index 00000000000..bdd0ede1a19
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/manifest/tests/test_manifest.py
@@ -0,0 +1,55 @@
+from .. import manifest, item as manifestitem, sourcefile
+
+
+def test_local_reftest_add():
+ m = manifest.Manifest()
+ s = sourcefile.SourceFile("/", "test", "/")
+ test = manifestitem.RefTest(s, "/test", [("/ref", "==")])
+ m.local_changes.add(test)
+ assert list(m) == [(test.path, {test})]
+
+
+def test_local_reftest_delete_path():
+ m = manifest.Manifest()
+ s = sourcefile.SourceFile("/", "test", "/")
+ test = manifestitem.RefTest(s, "/test", [("/ref", "==")])
+ m.add(test)
+ m.local_changes.add_deleted(test.path)
+ assert list(m) == []
+
+
+def test_local_reftest_adjusted():
+ m = manifest.Manifest()
+ s = sourcefile.SourceFile("/", "test", "/")
+ test = manifestitem.RefTest(s, "/test", [("/ref", "==")])
+ m.add(test)
+
+ assert list(m) == [(test.path, {test})]
+
+ assert m.compute_reftests({test.path: {test}}) == {test}
+
+ test_1 = manifestitem.RefTest(s, "/test-1", [("/test", "==")])
+ m.local_changes.add(test_1)
+
+ assert m.compute_reftests({test.path: {test}, test_1.path: {test_1}}) == {test_1}
+
+ m.local_changes._deleted_reftests[test.path] = {test}
+
+ assert list(m) == [(test_1.path, {test_1})]
+
+
+def test_manifest_to_json():
+ m = manifest.Manifest()
+ s = sourcefile.SourceFile("/", "test", "/")
+ test = manifestitem.RefTest(s, "/test", [("/ref", "==")])
+ m.add(test)
+ test_1 = manifestitem.RefTest(s, "/test-1", [("/test", "==")])
+ m.local_changes.add(test_1)
+ m.local_changes._deleted_reftests[test.path] = {test}
+
+ json_str = m.to_json()
+ loaded = manifest.Manifest.from_json("/", json_str)
+
+ assert list(loaded) == list(m)
+
+ assert loaded.to_json() == json_str
diff --git a/tests/wpt/web-platform-tests/uievents/order-of-events/focus-events/focus-manual.html b/tests/wpt/web-platform-tests/uievents/order-of-events/focus-events/focus-manual.html
new file mode 100644
index 00000000000..c91f790e21e
--- /dev/null
+++ b/tests/wpt/web-platform-tests/uievents/order-of-events/focus-events/focus-manual.html
@@ -0,0 +1,81 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Focus-related events should fire in the correct order</title>
+ <link rel="author" title="Chris Rebert" href="http://chrisrebert.com">
+ <link rel="help" href="https://w3c.github.io/uievents/#events-focusevent-event-order">
+ <meta name="flags" content="interact">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <ol>
+ <li>Click into the first text input.</li>
+ <li>Click into the second text input.</li>
+ <li>Click the "Done" button.</li>
+ </ol>
+
+ <input type="text" id="a" value="First">
+ <br>
+ <input type="text" id="b" value="Second">
+ <br>
+ <button type="button" id="done">Done</button>
+
+ <script>
+setup({explicit_timeout: true});
+var done = false;
+var events = [];
+var targets = [];
+function record(e) {
+ if (done) {
+ return;
+ }
+ events.push(e.type);
+ targets.push(e.target.id);
+}
+function finish() {
+ done = true;
+}
+var relevantEvents = [
+ 'focus',
+ 'blur',
+ 'focusin',
+ 'focusout'
+];
+window.onload = function () {
+ var a = document.getElementById('a');
+ var b = document.getElementById('b');
+ var inputs = [a, b];
+
+ b.addEventListener('blur', finish, false);
+ b.addEventListener('focusout', finish, false);
+
+ for (var i = 0; i < inputs.length; i++) {
+ for (var k = 0; k < relevantEvents.length; k++) {
+ inputs[i].addEventListener(relevantEvents[k], record, false);
+ }
+ }
+
+ async_test(function(t) {
+ document.getElementById('done').addEventListener('click', function () {
+ finish();
+ t.step(function () {
+ assert_array_equals(
+ events,
+ ['focusin', 'focus', 'focusout', 'focusin', 'blur', 'focus'],
+ 'Focus-related events should fire in this order: focusin, focus, focusout, focusin, blur, focus'
+ );
+ assert_array_equals(
+ targets,
+ [ 'a', 'a', 'a', 'b', 'a', 'b'],
+ 'Focus-related events should fire at the correct targets'
+ );
+ t.done();
+ });
+ }, false);
+ }, 'Focus-related events should fire in the correct order');
+};
+ </script>
+ </body>
+</html>
diff --git a/tests/wpt/web-platform-tests/uievents/order-of-events/focus-events/legacy-manual.html b/tests/wpt/web-platform-tests/uievents/order-of-events/focus-events/legacy-manual.html
new file mode 100644
index 00000000000..e71273973e6
--- /dev/null
+++ b/tests/wpt/web-platform-tests/uievents/order-of-events/focus-events/legacy-manual.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Focus-related events (including legacy events) should fire in the correct order</title>
+ <link rel="author" title="Chris Rebert" href="http://chrisrebert.com">
+ <link rel="help" href="https://w3c.github.io/uievents/#legacy-focusevent-event-order">
+ <meta name="flags" content="interact">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <ol>
+ <li>Click into the first text input.</li>
+ <li>Click into the second text input.</li>
+ <li>Click the "Done" button.</li>
+ </ol>
+
+ <input type="text" id="a" value="First">
+ <br>
+ <input type="text" id="b" value="Second">
+ <br>
+ <button type="button" id="done">Done</button>
+
+ <script>
+setup({explicit_timeout: true});
+var done = false;
+var events = [];
+var targets = [];
+function record(e) {
+ if (done) {
+ return;
+ }
+ events.push(e.type);
+ targets.push(e.target.id);
+}
+function finish() {
+ done = true;
+}
+var relevantEvents = [
+ 'focus',
+ 'blur',
+ 'focusin',
+ 'focusout',
+ 'DOMFocusIn',
+ 'DOMFocusOut'
+];
+window.onload = function () {
+ var a = document.getElementById('a');
+ var b = document.getElementById('b');
+ var inputs = [a, b];
+
+ b.addEventListener('blur', finish, false);
+ b.addEventListener('focusout', finish, false);
+ b.addEventListener('DOMFocusOut', finish, false);
+
+ for (var i = 0; i < inputs.length; i++) {
+ for (var k = 0; k < relevantEvents.length; k++) {
+ inputs[i].addEventListener(relevantEvents[k], record, false);
+ }
+ }
+
+ async_test(function(t) {
+ document.getElementById('done').addEventListener('click', function () {
+ finish();
+ t.step(function () {
+ assert_array_equals(
+ events,
+ ['focusin', 'focus', 'DOMFocusIn', 'focusout', 'focusin', 'blur', 'DOMFocusOut', 'focus', 'DOMFocusIn'],
+ 'Focus-related events should fire in this order: focusin, focus, DOMFocusIn, focusout, focusin, blur, DOMFocusOut, focus, DOMFocusIn'
+ );
+ assert_array_equals(
+ targets,
+ [ 'a', 'a', 'a', 'a', 'b', 'a', 'a', 'b', 'b'],
+ 'Focus-related events should fire at the correct targets'
+ );
+ t.done();
+ });
+ }, false);
+ }, 'Focus-related events should fire in the correct order');
+};
+ </script>
+ </body>
+</html>
diff --git a/tests/wpt/web-platform-tests/web-animations/animation-effect-timing/easing.html b/tests/wpt/web-platform-tests/web-animations/animation-effect-timing/easing.html
new file mode 100644
index 00000000000..d3fed91a37d
--- /dev/null
+++ b/tests/wpt/web-platform-tests/web-animations/animation-effect-timing/easing.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>easing tests</title>
+<link rel="help" href="https://w3c.github.io/web-animations/#dom-animationeffecttiming-easing">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../testcommon.js"></script>
+<script src="../resources/effect-easing-tests.js"></script>
+<body>
+<div id="log"></div>
+<script>
+'use strict';
+
+function assert_progress(animation, currentTime, easingFunction) {
+ animation.currentTime = currentTime;
+ var portion = currentTime / animation.effect.timing.duration;
+ assert_approx_equals(animation.effect.getComputedTiming().progress,
+ easingFunction(portion),
+ 0.01,
+ 'The progress of the animation should be approximately ' +
+ easingFunction(portion) + ' at ' + currentTime + 'ms');
+}
+
+gEffectEasingTests.forEach(function(options) {
+ test(function(t) {
+ var target = createDiv(t);
+ var anim = target.animate([ { opacity: 0 }, { opacity: 1 } ],
+ { duration: 1000 * MS_PER_SEC,
+ fill: 'forwards' });
+ anim.effect.timing.easing = options.easing;
+ assert_equals(anim.effect.timing.easing, options.easing);
+
+ var easing = options.easingFunction;
+ assert_progress(anim, 0, easing);
+ assert_progress(anim, 250 * MS_PER_SEC, easing);
+ assert_progress(anim, 500 * MS_PER_SEC, easing);
+ assert_progress(anim, 750 * MS_PER_SEC, easing);
+ assert_progress(anim, 1000 * MS_PER_SEC, easing);
+ }, options.desc);
+});
+
+test(function(t) {
+ var div = createDiv(t);
+ var anim = div.animate({ opacity: [ 0, 1 ] }, 100 * MS_PER_SEC);
+ assert_throws({ name: 'TypeError' },
+ function() {
+ anim.effect.timing.easing = '';
+ });
+ assert_throws({ name: 'TypeError' },
+ function() {
+ anim.effect.timing.easing = 'test';
+ });
+}, 'Test invalid easing value');
+
+test(function(t) {
+ var delay = 1000 * MS_PER_SEC;
+
+ var target = createDiv(t);
+ var anim = target.animate([ { opacity: 0 }, { opacity: 1 } ],
+ { duration: 1000 * MS_PER_SEC,
+ fill: 'both',
+ delay: delay,
+ easing: 'steps(2, start)' });
+
+ anim.effect.timing.easing = 'steps(2, end)';
+ assert_equals(anim.effect.getComputedTiming().progress, 0,
+ 'easing replace to steps(2, end) at before phase');
+
+ anim.currentTime = delay + 750 * MS_PER_SEC;
+ assert_equals(anim.effect.getComputedTiming().progress, 0.5,
+ 'change currentTime to active phase');
+
+ anim.effect.timing.easing = 'steps(2, start)';
+ assert_equals(anim.effect.getComputedTiming().progress, 1,
+ 'easing replace to steps(2, start) at active phase');
+
+ anim.currentTime = delay + 1500 * MS_PER_SEC;
+ anim.effect.timing.easing = 'steps(2, end)';
+ assert_equals(anim.effect.getComputedTiming().progress, 1,
+ 'easing replace to steps(2, end) again at after phase');
+}, 'Change the easing while the animation is running');
+
+</script>
+</body>
diff --git a/tests/wpt/web-platform-tests/web-animations/animation-effect-timing/fill.html b/tests/wpt/web-platform-tests/web-animations/animation-effect-timing/fill.html
new file mode 100644
index 00000000000..e635bebae1c
--- /dev/null
+++ b/tests/wpt/web-platform-tests/web-animations/animation-effect-timing/fill.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>fill tests</title>
+<link rel="help" href="https://w3c.github.io/web-animations/#dom-animationeffecttiming-fill">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../testcommon.js"></script>
+<link rel="stylesheet" href="/resources/testharness.css">
+<body>
+<div id="log"></div>
+<script>
+'use strict';
+
+["none", "forwards", "backwards", "both", ].forEach(function(fill){
+ test(function(t) {
+ var div = createDiv(t);
+ var anim = div.animate({ opacity: [ 0, 1 ] }, 100);
+ anim.effect.timing.fill = fill;
+ assert_equals(anim.effect.timing.fill, fill, 'set fill ' + fill);
+ assert_equals(anim.effect.getComputedTiming().fill, fill, 'getComputedTiming() after set fill ' + fill);
+ }, 'set fill ' + fill);
+});
+
+</script>
+</body>
diff --git a/tests/wpt/web-platform-tests/web-animations/animation-model/animation-types/discrete-animation.html b/tests/wpt/web-platform-tests/web-animations/animation-model/animation-types/discrete-animation.html
new file mode 100644
index 00000000000..864a9e2845b
--- /dev/null
+++ b/tests/wpt/web-platform-tests/web-animations/animation-model/animation-types/discrete-animation.html
@@ -0,0 +1,136 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Tests for discrete animation</title>
+<link rel="help" href="http://w3c.github.io/web-animations/#animatable-as-string-section">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
+<link rel="stylesheet" href="/resources/testharness.css">
+<body>
+<div id="log"></div>
+<script>
+'use strict';
+
+test(function(t) {
+ var div = createDiv(t);
+
+ var anim = div.animate({ fontStyle: [ 'normal', 'italic' ] },
+ { duration: 1000, fill: 'forwards' });
+
+ assert_equals(getComputedStyle(div).fontStyle, 'normal',
+ 'Animation produces \'from\' value at start of interval');
+ anim.currentTime = anim.effect.getComputedTiming().duration / 2 - 1;
+ assert_equals(getComputedStyle(div).fontStyle, 'normal',
+ 'Animation produces \'from\' value just before the middle of'
+ + ' the interval');
+ anim.currentTime++;
+ assert_equals(getComputedStyle(div).fontStyle, 'italic',
+ 'Animation produces \'to\' value at exact middle of'
+ + ' the interval');
+ anim.finish();
+ assert_equals(getComputedStyle(div).fontStyle, 'italic',
+ 'Animation produces \'to\' value during forwards fill');
+}, 'Test animating discrete values');
+
+test(function(t) {
+ var div = createDiv(t);
+ var originalHeight = getComputedStyle(div).height;
+
+ var anim = div.animate({ height: [ 'auto', '200px' ] },
+ { duration: 1000, fill: 'forwards' });
+
+ assert_equals(getComputedStyle(div).height, originalHeight,
+ 'Animation produces \'from\' value at start of interval');
+ anim.currentTime = anim.effect.getComputedTiming().duration / 2 - 1;
+ assert_equals(getComputedStyle(div).height, originalHeight,
+ 'Animation produces \'from\' value just before the middle of'
+ + ' the interval');
+ anim.currentTime++;
+ assert_equals(getComputedStyle(div).height, '200px',
+ 'Animation produces \'to\' value at exact middle of'
+ + ' the interval');
+ anim.finish();
+ assert_equals(getComputedStyle(div).height, '200px',
+ 'Animation produces \'to\' value during forwards fill');
+}, 'Test discrete animation is used when interpolation fails');
+
+test(function(t) {
+ var div = createDiv(t);
+ var originalHeight = getComputedStyle(div).height;
+
+ var anim = div.animate({ height: [ 'auto',
+ '200px',
+ '300px',
+ 'auto',
+ '400px' ] },
+ { duration: 1000, fill: 'forwards' });
+
+ // There are five values, so there are four pairs to try to interpolate.
+ // We test at the middle of each pair.
+ assert_equals(getComputedStyle(div).height, originalHeight,
+ 'Animation produces \'from\' value at start of interval');
+ anim.currentTime = 125;
+ assert_equals(getComputedStyle(div).height, '200px',
+ 'First non-interpolable pair uses discrete interpolation');
+ anim.currentTime += 250;
+ assert_equals(getComputedStyle(div).height, '250px',
+ 'Second interpolable pair uses linear interpolation');
+ anim.currentTime += 250;
+ assert_equals(getComputedStyle(div).height, originalHeight,
+ 'Third non-interpolable pair uses discrete interpolation');
+ anim.currentTime += 250;
+ assert_equals(getComputedStyle(div).height, '400px',
+ 'Fourth non-interpolable pair uses discrete interpolation');
+}, 'Test discrete animation is used only for pairs of values that cannot'
+ + ' be interpolated');
+
+test(function(t) {
+ var div = createDiv(t);
+ var originalHeight = getComputedStyle(div).height;
+
+ // Easing: http://cubic-bezier.com/#.68,0,1,.01
+ // With this curve, we don't reach the 50% point until about 95% of
+ // the time has expired.
+ var anim = div.animate({ fontStyle: [ 'italic', 'oblique' ] },
+ { duration: 1000, fill: 'forwards',
+ easing: 'cubic-bezier(0.68,0,1,0.01)' });
+
+ assert_equals(getComputedStyle(div).fontStyle, 'italic',
+ 'Animation produces \'from\' value at start of interval');
+ anim.currentTime = 940;
+ assert_equals(getComputedStyle(div).fontStyle, 'italic',
+ 'Animation produces \'from\' value at 94% of the iteration'
+ + ' time');
+ anim.currentTime = 960;
+ assert_equals(getComputedStyle(div).fontStyle, 'oblique',
+ 'Animation produces \'to\' value at 96% of the iteration'
+ + ' time');
+}, 'Test the 50% switch point for discrete animation is based on the'
+ + ' effect easing');
+
+test(function(t) {
+ var div = createDiv(t);
+ var originalHeight = getComputedStyle(div).height;
+
+ // Easing: http://cubic-bezier.com/#.68,0,1,.01
+ // With this curve, we don't reach the 50% point until about 95% of
+ // the time has expired.
+ var anim = div.animate([ { fontStyle: 'italic',
+ easing: 'cubic-bezier(0.68,0,1,0.01)' },
+ { fontStyle: 'oblique' } ],
+ { duration: 1000, fill: 'forwards' });
+
+ assert_equals(getComputedStyle(div).fontStyle, 'italic',
+ 'Animation produces \'from\' value at start of interval');
+ anim.currentTime = 940;
+ assert_equals(getComputedStyle(div).fontStyle, 'italic',
+ 'Animation produces \'from\' value at 94% of the iteration'
+ + ' time');
+ anim.currentTime = 960;
+ assert_equals(getComputedStyle(div).fontStyle, 'oblique',
+ 'Animation produces \'to\' value at 96% of the iteration'
+ + ' time');
+}, 'Test the 50% switch point for discrete animation is based on the'
+ + ' keyframe easing');
+
+</script>
diff --git a/tests/wpt/web-platform-tests/web-animations/animation-model/animation-types/not-animatable.html b/tests/wpt/web-platform-tests/web-animations/animation-model/animation-types/not-animatable.html
new file mode 100644
index 00000000000..653c78036e4
--- /dev/null
+++ b/tests/wpt/web-platform-tests/web-animations/animation-model/animation-types/not-animatable.html
@@ -0,0 +1,120 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Tests for not animatable properties</title>
+<link rel="help" href="https://w3c.github.io/web-animations/#not-animatable-section">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
+<body>
+<div id="log"></div>
+<script>
+'use strict';
+
+test(function(t) {
+ var div = createDiv(t);
+ var anim = div.animate({ display: [ 'inline', 'inline-block' ] }, 1000);
+
+ assert_equals(anim.effect.getFrames().length, 0,
+ 'Animation specified using property-indexed notation but'
+ + ' consisting of only non-animatable properties should not'
+ + ' contain any keyframes');
+}, '\'display\' property cannot be animated using property-indexed notation');
+
+test(function(t) {
+ var div = createDiv(t);
+ var anim = div.animate([ { display: 'inline' }, { display: 'inline-block' } ],
+ 1000);
+
+ assert_equals(anim.effect.getFrames().length, 2,
+ 'Animation specified using a keyframe sequence where each'
+ + ' keyframe contains only non-animatable properties should'
+ + ' return an equal number of (empty) keyframes');
+ assert_false(anim.effect.getFrames()[0].hasOwnProperty('display'),
+ 'Initial keyframe should not have the \'display\' property');
+ assert_false(anim.effect.getFrames()[1].hasOwnProperty('display'),
+ 'Final keyframe should not have the \'display\' property');
+}, '\'display\' property cannot be animated using a keyframe sequence');
+
+test(function(t) {
+ var properties = {
+ // CSS Animations properties
+ animation: [ 'anim 1s', 'anim 2s' ],
+ animationName: [ 'abc', 'xyz' ],
+ animationTimingFunction: [ 'ease', 'steps(2)' ],
+ animationDelay: [ '1s', '2s' ],
+ animationIterationCount: [ 1, 2 ],
+ animationDirection: [ 'normal', 'reverse' ],
+ animationFillMode: [ 'forwards', 'backwards' ],
+ animationPlayState: [ 'paused', 'running' ],
+
+ // CSS Transitions properties
+ transition: [ 'all 1s', 'all 2s' ],
+ transitionDelay: [ '1s', '2s' ],
+ transitionDuration: [ '1s', '2s' ],
+ transitionProperty: [ 'all', 'opacity' ],
+ transitionTimingFunction: [ 'ease', 'ease-out' ]
+ };
+
+ var div = createDiv(t);
+ var anim = div.animate(properties, 1000);
+
+ assert_equals(anim.effect.getFrames().length, 0,
+ 'Animation specified using property-indexed notation but'
+ + ' consisting of only non-animatable properties should not'
+ + ' contain any keyframes');
+}, 'CSS animations and CSS transitions properties cannot be animated using'
+ + ' property-indexed notation');
+
+test(function(t) {
+ var frames = [
+ {
+ animation: 'anim 1s',
+ animationName: 'abc',
+ animationTimingFunction: 'ease',
+ animationDelay: '1s',
+ animationIterationCount: 1,
+ animationDirection: 'normal',
+ animationFillMode: 'forwards',
+ animationPlayState: 'paused',
+ transition: 'all 1s',
+ transitionDelay: '1s',
+ transitionDuration: '1s',
+ transitionProperty: 'opacity',
+ transitionTimingFunction: 'ease'
+ },
+ {
+ animation: 'anim 2s',
+ animationName: 'xyz',
+ animationTimingFunction: 'steps(2)',
+ animationDelay: '2s',
+ animationIterationCount: 2,
+ animationDirection: 'reverse',
+ animationFillMode: 'backwards',
+ animationPlayState: 'running',
+ transition: 'all 2s',
+ transitionDelay: '2s',
+ transitionDuration: '2s',
+ transitionProperty: 'all',
+ transitionTimingFunction: 'ease-out'
+ }
+ ];
+ var defaultKeyframeProperties = [ 'computedOffset', 'easing', 'offset' ];
+
+ var div = createDiv(t);
+ var anim = div.animate(frames, 1000);
+
+ assert_equals(anim.effect.getFrames().length, 2,
+ 'Animation specified using a keyframe sequence where each'
+ + ' keyframe contains only non-animatable properties should'
+ + ' return an equal number of (empty) keyframes');
+ assert_array_equals(Object.keys(anim.effect.getFrames()[0]),
+ defaultKeyframeProperties,
+ 'Initial keyframe should not contain any properties other'
+ + ' than the default keyframe properties');
+ assert_array_equals(Object.keys(anim.effect.getFrames()[1]),
+ defaultKeyframeProperties,
+ 'Final keyframe should not contain any properties other'
+ + ' than the default keyframe properties');
+}, 'CSS animations and CSS transitions properties cannot be animated using'
+ + ' a sequence of keyframes');
+</script>
diff --git a/tests/wpt/web-platform-tests/web-animations/animation-model/keyframes/effect-value-context.html b/tests/wpt/web-platform-tests/web-animations/animation-model/keyframes/effect-value-context.html
new file mode 100644
index 00000000000..e2af80dff77
--- /dev/null
+++ b/tests/wpt/web-platform-tests/web-animations/animation-model/keyframes/effect-value-context.html
@@ -0,0 +1,86 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Tests that property values respond to changes to their context</title>
+<link rel="help" href="https://w3c.github.io/web-animations/#keyframes-section">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../../testcommon.js"></script>
+<link rel="stylesheet" href="/resources/testharness.css">
+<body>
+<div id="log"></div>
+<script>
+
+test(function(t) {
+ var div = createDiv(t);
+ div.style.fontSize = '10px';
+ var animation = div.animate([ { marginLeft: '10em' },
+ { marginLeft: '20em' } ], 1000);
+ animation.currentTime = 500;
+ assert_equals(getComputedStyle(div).marginLeft, '150px',
+ 'Effect value before updating font-size');
+ div.style.fontSize = '20px';
+ assert_equals(getComputedStyle(div).marginLeft, '300px',
+ 'Effect value after updating font-size');
+}, 'Effect values reflect changes to font-size on element');
+
+test(function(t) {
+ var parentDiv = createDiv(t);
+ var div = createDiv(t);
+ parentDiv.appendChild(div);
+ parentDiv.style.fontSize = '10px';
+
+ var animation = div.animate([ { marginLeft: '10em' },
+ { marginLeft: '20em' } ], 1000);
+ animation.currentTime = 500;
+ assert_equals(getComputedStyle(div).marginLeft, '150px',
+ 'Effect value before updating font-size on parent element');
+ parentDiv.style.fontSize = '20px';
+ assert_equals(getComputedStyle(div).marginLeft, '300px',
+ 'Effect value after updating font-size on parent element');
+}, 'Effect values reflect changes to font-size on parent element');
+
+promise_test(function(t) {
+ var parentDiv = createDiv(t);
+ var div = createDiv(t);
+ parentDiv.appendChild(div);
+ parentDiv.style.fontSize = '10px';
+ var animation = div.animate([ { marginLeft: '10em' },
+ { marginLeft: '20em' } ], 1000);
+
+ animation.pause();
+ animation.currentTime = 500;
+ parentDiv.style.fontSize = '20px';
+
+ return animation.ready.then(function() {
+ assert_equals(getComputedStyle(div).marginLeft, '300px',
+ 'Effect value after updating font-size on parent element');
+ });
+}, 'Effect values reflect changes to font-size when computed style is not'
+ + ' immediately flushed');
+
+promise_test(function(t) {
+ var divWith10pxFontSize = createDiv(t);
+ divWith10pxFontSize.style.fontSize = '10px';
+ var divWith20pxFontSize = createDiv(t);
+ divWith20pxFontSize.style.fontSize = '20px';
+
+ var div = createDiv(t);
+ div.remove(); // Detach
+ var animation = div.animate([ { marginLeft: '10em' },
+ { marginLeft: '20em' } ], 1000);
+ animation.pause();
+
+ return animation.ready.then(function() {
+ animation.currentTime = 500;
+
+ divWith10pxFontSize.appendChild(div);
+ assert_equals(getComputedStyle(div).marginLeft, '150px',
+ 'Effect value after attaching to font-size:10px parent');
+ divWith20pxFontSize.appendChild(div);
+ assert_equals(getComputedStyle(div).marginLeft, '300px',
+ 'Effect value after attaching to font-size:20px parent');
+ });
+}, 'Effect values reflect changes to font-size from reparenting');
+
+</script>
+</body>
diff --git a/tests/wpt/web-platform-tests/web-animations/animation/finished.html b/tests/wpt/web-platform-tests/web-animations/animation/finished.html
new file mode 100644
index 00000000000..716fa9571b8
--- /dev/null
+++ b/tests/wpt/web-platform-tests/web-animations/animation/finished.html
@@ -0,0 +1,371 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Animation.finished</title>
+<link rel="help" href="https://w3c.github.io/web-animations/#dom-animation-finished">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../testcommon.js"></script>
+<link rel="stylesheet" href="/resources/testharness.css">
+<body>
+<div id="log"></div>
+<script>
+"use strict";
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+ var previousFinishedPromise = animation.finished;
+ return animation.ready.then(function() {
+ assert_equals(animation.finished, previousFinishedPromise,
+ 'Finished promise is the same object when playing starts');
+ animation.pause();
+ assert_equals(animation.finished, previousFinishedPromise,
+ 'Finished promise does not change when pausing');
+ animation.play();
+ assert_equals(animation.finished, previousFinishedPromise,
+ 'Finished promise does not change when play() unpauses');
+
+ animation.currentTime = 100 * MS_PER_SEC;
+
+ return animation.finished;
+ }).then(function() {
+ assert_equals(animation.finished, previousFinishedPromise,
+ 'Finished promise is the same object when playing completes');
+ });
+}, 'Test pausing then playing does not change the finished promise');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+ var previousFinishedPromise = animation.finished;
+ animation.finish();
+ return animation.finished.then(function() {
+ assert_equals(animation.finished, previousFinishedPromise,
+ 'Finished promise is the same object when playing completes');
+ animation.play();
+ assert_not_equals(animation.finished, previousFinishedPromise,
+ 'Finished promise changes when replaying animation');
+
+ previousFinishedPromise = animation.finished;
+ animation.play();
+ assert_equals(animation.finished, previousFinishedPromise,
+ 'Finished promise is the same after redundant play() call');
+
+ });
+}, 'Test restarting a finished animation');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+ var previousFinishedPromise;
+ animation.finish();
+ return animation.finished.then(function() {
+ previousFinishedPromise = animation.finished;
+ animation.playbackRate = -1;
+ assert_not_equals(animation.finished, previousFinishedPromise,
+ 'Finished promise should be replaced when reversing a ' +
+ 'finished promise');
+ animation.currentTime = 0;
+ return animation.finished;
+ }).then(function() {
+ previousFinishedPromise = animation.finished;
+ animation.play();
+ assert_not_equals(animation.finished, previousFinishedPromise,
+ 'Finished promise is replaced after play() call on ' +
+ 'finished, reversed animation');
+ });
+}, 'Test restarting a reversed finished animation');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+ var previousFinishedPromise = animation.finished;
+ animation.finish();
+ return animation.finished.then(function() {
+ animation.currentTime = 100 * MS_PER_SEC + 1000;
+ assert_equals(animation.finished, previousFinishedPromise,
+ 'Finished promise is unchanged jumping past end of ' +
+ 'finished animation');
+ });
+}, 'Test redundant finishing of animation');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+ // Setup callback to run if finished promise is resolved
+ var finishPromiseResolved = false;
+ animation.finished.then(function() {
+ finishPromiseResolved = true;
+ });
+ return animation.ready.then(function() {
+ // Jump to mid-way in interval and pause
+ animation.currentTime = 100 * MS_PER_SEC / 2;
+ animation.pause();
+ return animation.ready;
+ }).then(function() {
+ // Jump to the end
+ // (But don't use finish() since that should unpause as well)
+ animation.currentTime = 100 * MS_PER_SEC;
+ return waitForAnimationFrames(2);
+ }).then(function() {
+ assert_false(finishPromiseResolved,
+ 'Finished promise should not resolve when paused');
+ });
+}, 'Finished promise does not resolve when paused');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+ // Setup callback to run if finished promise is resolved
+ var finishPromiseResolved = false;
+ animation.finished.then(function() {
+ finishPromiseResolved = true;
+ });
+ return animation.ready.then(function() {
+ // Jump to mid-way in interval and pause
+ animation.currentTime = 100 * MS_PER_SEC / 2;
+ animation.pause();
+ // Jump to the end
+ animation.currentTime = 100 * MS_PER_SEC;
+ return waitForAnimationFrames(2);
+ }).then(function() {
+ assert_false(finishPromiseResolved,
+ 'Finished promise should not resolve when pause-pending');
+ });
+}, 'Finished promise does not resolve when pause-pending');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+ animation.finish();
+ return animation.finished.then(function(resolvedAnimation) {
+ assert_equals(resolvedAnimation, animation,
+ 'Object identity of animation passed to Promise callback'
+ + ' matches the animation object owning the Promise');
+ });
+}, 'The finished promise is fulfilled with its Animation');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+ var previousFinishedPromise = animation.finished;
+
+ // Set up listeners on finished promise
+ var retPromise = animation.finished.then(function() {
+ assert_unreached('finished promise was fulfilled');
+ }).catch(function(err) {
+ assert_equals(err.name, 'AbortError',
+ 'finished promise is rejected with AbortError');
+ assert_not_equals(animation.finished, previousFinishedPromise,
+ 'Finished promise should change after the original is ' +
+ 'rejected');
+ });
+
+ animation.cancel();
+
+ return retPromise;
+}, 'finished promise is rejected when an animation is cancelled by calling ' +
+ 'cancel()');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+ var previousFinishedPromise = animation.finished;
+ animation.finish();
+ return animation.finished.then(function() {
+ animation.cancel();
+ assert_not_equals(animation.finished, previousFinishedPromise,
+ 'A new finished promise should be created when'
+ + ' cancelling a finished animation');
+ });
+}, 'cancelling an already-finished animation replaces the finished promise');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+ animation.cancel();
+ // The spec says we still create a new finished promise and reject the old
+ // one even if we're already idle. That behavior might change, but for now
+ // test that we do that.
+ var retPromise = animation.finished.catch(function(err) {
+ assert_equals(err.name, 'AbortError',
+ 'finished promise is rejected with AbortError');
+ });
+
+ // Redundant call to cancel();
+ var previousFinishedPromise = animation.finished;
+ animation.cancel();
+ assert_not_equals(animation.finished, previousFinishedPromise,
+ 'A redundant call to cancel() should still generate a new'
+ + ' finished promise');
+ return retPromise;
+}, 'cancelling an idle animation still replaces the finished promise');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+ const HALF_DUR = 100 * MS_PER_SEC / 2;
+ const QUARTER_DUR = 100 * MS_PER_SEC / 4;
+ var gotNextFrame = false;
+ var currentTimeBeforeShortening;
+ animation.currentTime = HALF_DUR;
+ return animation.ready.then(function() {
+ currentTimeBeforeShortening = animation.currentTime;
+ animation.effect.timing.duration = QUARTER_DUR;
+ // Below we use gotNextFrame to check that shortening of the animation
+ // duration causes the finished promise to resolve, rather than it just
+ // getting resolved on the next animation frame. This relies on the fact
+ // that the promises are resolved as a micro-task before the next frame
+ // happens.
+ waitForAnimationFrames(1).then(function() {
+ gotNextFrame = true;
+ });
+
+ return animation.finished;
+ }).then(function() {
+ assert_false(gotNextFrame, 'shortening of the animation duration should ' +
+ 'resolve the finished promise');
+ assert_equals(animation.currentTime, currentTimeBeforeShortening,
+ 'currentTime should be unchanged when duration shortened');
+ var previousFinishedPromise = animation.finished;
+ animation.effect.timing.duration = 100 * MS_PER_SEC;
+ assert_not_equals(animation.finished, previousFinishedPromise,
+ 'Finished promise should change after lengthening the ' +
+ 'duration causes the animation to become active');
+ });
+}, 'Test finished promise changes for animation duration changes');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+ var retPromise = animation.ready.then(function() {
+ animation.playbackRate = 0;
+ animation.currentTime = 100 * MS_PER_SEC + 1000;
+ return waitForAnimationFrames(2);
+ });
+
+ animation.finished.then(t.step_func(function() {
+ assert_unreached('finished promise should not resolve when playbackRate ' +
+ 'is zero');
+ }));
+
+ return retPromise;
+}, 'Test finished promise changes when playbackRate == 0');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+ return animation.ready.then(function() {
+ animation.playbackRate = -1;
+ return animation.finished;
+ });
+}, 'Test finished promise resolves when reaching to the natural boundary.');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+ var previousFinishedPromise = animation.finished;
+ animation.finish();
+ return animation.finished.then(function() {
+ animation.currentTime = 0;
+ assert_not_equals(animation.finished, previousFinishedPromise,
+ 'Finished promise should change once a prior ' +
+ 'finished promise resolved and the animation ' +
+ 'falls out finished state');
+ });
+}, 'Test finished promise changes when a prior finished promise resolved ' +
+ 'and the animation falls out finished state');
+
+test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+ var previousFinishedPromise = animation.finished;
+ animation.currentTime = 100 * MS_PER_SEC;
+ animation.currentTime = 100 * MS_PER_SEC / 2;
+ assert_equals(animation.finished, previousFinishedPromise,
+ 'No new finished promise generated when finished state ' +
+ 'is checked asynchronously');
+}, 'Test no new finished promise generated when finished state ' +
+ 'is checked asynchronously');
+
+test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+ var previousFinishedPromise = animation.finished;
+ animation.finish();
+ animation.currentTime = 100 * MS_PER_SEC / 2;
+ assert_not_equals(animation.finished, previousFinishedPromise,
+ 'New finished promise generated when finished state ' +
+ 'is checked synchronously');
+}, 'Test new finished promise generated when finished state ' +
+ 'is checked synchronously');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+ var resolvedFinished = false;
+ animation.finished.then(function() {
+ resolvedFinished = true;
+ });
+ return animation.ready.then(function() {
+ animation.finish();
+ animation.currentTime = 100 * MS_PER_SEC / 2;
+ }).then(function() {
+ assert_true(resolvedFinished,
+ 'Animation.finished should be resolved even if ' +
+ 'the finished state is changed soon');
+ });
+
+}, 'Test synchronous finished promise resolved even if finished state ' +
+ 'is changed soon');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+ var resolvedFinished = false;
+ animation.finished.then(function() {
+ resolvedFinished = true;
+ });
+
+ return animation.ready.then(function() {
+ animation.currentTime = 100 * MS_PER_SEC;
+ animation.finish();
+ }).then(function() {
+ assert_true(resolvedFinished,
+ 'Animation.finished should be resolved soon after finish() is ' +
+ 'called even if there are other asynchronous promises just before it');
+ });
+}, 'Test synchronous finished promise resolved even if asynchronous ' +
+ 'finished promise happens just before synchronous promise');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+ animation.finished.then(t.step_func(function() {
+ assert_unreached('Animation.finished should not be resolved');
+ }));
+
+ return animation.ready.then(function() {
+ animation.currentTime = 100 * MS_PER_SEC;
+ animation.currentTime = 100 * MS_PER_SEC / 2;
+ });
+}, 'Test finished promise is not resolved when the animation ' +
+ 'falls out finished state immediately');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+ return animation.ready.then(function() {
+ animation.currentTime = 100 * MS_PER_SEC;
+ animation.finished.then(t.step_func(function() {
+ assert_unreached('Animation.finished should not be resolved');
+ }));
+ animation.currentTime = 0;
+ });
+
+}, 'Test finished promise is not resolved once the animation ' +
+ 'falls out finished state even though the current finished ' +
+ 'promise is generated soon after animation state became finished');
+
+</script>
+</body>
diff --git a/tests/wpt/web-platform-tests/web-animations/animation/id.html b/tests/wpt/web-platform-tests/web-animations/animation/id.html
new file mode 100644
index 00000000000..65e10922697
--- /dev/null
+++ b/tests/wpt/web-platform-tests/web-animations/animation/id.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Animation.id</title>
+<link rel="help" href="https://w3c.github.io/web-animations/#dom-animation-id">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../testcommon.js"></script>
+<link rel="stylesheet" href="/resources/testharness.css">
+<body>
+<div id="log"></div>
+<script>
+"use strict";
+
+test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+ assert_equals(animation.id, '', 'id for CSS Animation is initially empty');
+ animation.id = 'anim'
+
+ assert_equals(animation.id, 'anim', 'animation.id reflects the value set');
+}, 'Animation.id for CSS Animations');
+
+</script>
+</body>
diff --git a/tests/wpt/web-platform-tests/web-animations/animation/oncancel.html b/tests/wpt/web-platform-tests/web-animations/animation/oncancel.html
new file mode 100644
index 00000000000..43f327b76f0
--- /dev/null
+++ b/tests/wpt/web-platform-tests/web-animations/animation/oncancel.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Animation.oncancel</title>
+<link rel="help" href="https://w3c.github.io/web-animations/#dom-animation-oncancel">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../testcommon.js"></script>
+<link rel="stylesheet" href="/resources/testharness.css">
+<body>
+<div id="log"></div>
+<script>
+"use strict";
+
+async_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+ var finishedTimelineTime;
+ animation.finished.then().catch(function() {
+ finishedTimelineTime = animation.timeline.currentTime;
+ });
+
+ animation.oncancel = t.step_func_done(function(event) {
+ assert_equals(event.currentTime, null,
+ 'event.currentTime should be null');
+ assert_equals(event.timelineTime, finishedTimelineTime,
+ 'event.timelineTime should equal to the animation timeline ' +
+ 'when finished promise is rejected');
+ });
+
+ animation.cancel();
+}, 'oncancel event is fired when animation.cancel() is called.');
+
+</script>
+</body>
diff --git a/tests/wpt/web-platform-tests/web-animations/animation/onfinish.html b/tests/wpt/web-platform-tests/web-animations/animation/onfinish.html
new file mode 100644
index 00000000000..459a54bc7ca
--- /dev/null
+++ b/tests/wpt/web-platform-tests/web-animations/animation/onfinish.html
@@ -0,0 +1,122 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Animation.onfinish</title>
+<link rel="help" href="https://w3c.github.io/web-animations/#dom-animation-onfinish">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../testcommon.js"></script>
+<link rel="stylesheet" href="/resources/testharness.css">
+<body>
+<div id="log"></div>
+<script>
+"use strict";
+
+async_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+ var finishedTimelineTime;
+ animation.finished.then(function() {
+ finishedTimelineTime = animation.timeline.currentTime;
+ });
+
+ animation.onfinish = t.step_func_done(function(event) {
+ assert_equals(event.currentTime, 0,
+ 'event.currentTime should be zero');
+ assert_equals(event.timelineTime, finishedTimelineTime,
+ 'event.timelineTime should equal to the animation timeline ' +
+ 'when finished promise is resolved');
+ });
+
+ animation.playbackRate = -1;
+}, 'onfinish event is fired when the currentTime < 0 and ' +
+ 'the playbackRate < 0');
+
+async_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+
+ var finishedTimelineTime;
+ animation.finished.then(function() {
+ finishedTimelineTime = animation.timeline.currentTime;
+ });
+
+ animation.onfinish = t.step_func_done(function(event) {
+ assert_equals(event.currentTime, 100 * MS_PER_SEC,
+ 'event.currentTime should be the effect end');
+ assert_equals(event.timelineTime, finishedTimelineTime,
+ 'event.timelineTime should equal to the animation timeline ' +
+ 'when finished promise is resolved');
+ });
+
+ animation.currentTime = 100 * MS_PER_SEC;
+}, 'onfinish event is fired when the currentTime > 0 and ' +
+ 'the playbackRate > 0');
+
+async_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+
+ var finishedTimelineTime;
+ animation.finished.then(function() {
+ finishedTimelineTime = animation.timeline.currentTime;
+ });
+
+ animation.onfinish = t.step_func_done(function(event) {
+ assert_equals(event.currentTime, 100 * MS_PER_SEC,
+ 'event.currentTime should be the effect end');
+ assert_equals(event.timelineTime, finishedTimelineTime,
+ 'event.timelineTime should equal to the animation timeline ' +
+ 'when finished promise is resolved');
+ });
+
+ animation.finish();
+}, 'onfinish event is fired when animation.finish() is called');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+
+ animation.onfinish = function(event) {
+ assert_unreached('onfinish event should not be fired');
+ };
+
+ animation.currentTime = 100 * MS_PER_SEC / 2;
+ animation.pause();
+
+ return animation.ready.then(function() {
+ animation.currentTime = 100 * MS_PER_SEC;
+ return waitForAnimationFrames(2);
+ });
+}, 'onfinish event is not fired when paused');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+ animation.onfinish = function(event) {
+ assert_unreached('onfinish event should not be fired');
+ };
+
+ return animation.ready.then(function() {
+ animation.playbackRate = 0;
+ animation.currentTime = 100 * MS_PER_SEC;
+ return waitForAnimationFrames(2);
+ });
+}, 'onfinish event is not fired when the playbackRate is zero');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+ animation.onfinish = function(event) {
+ assert_unreached('onfinish event should not be fired');
+ };
+
+ return animation.ready.then(function() {
+ animation.currentTime = 100 * MS_PER_SEC;
+ animation.currentTime = 100 * MS_PER_SEC / 2;
+ return waitForAnimationFrames(2);
+ });
+}, 'onfinish event is not fired when the animation falls out ' +
+ 'finished state immediately');
+
+</script>
+</body>
diff --git a/tests/wpt/web-platform-tests/web-animations/animation/pause.html b/tests/wpt/web-platform-tests/web-animations/animation/pause.html
new file mode 100644
index 00000000000..0b2c327786c
--- /dev/null
+++ b/tests/wpt/web-platform-tests/web-animations/animation/pause.html
@@ -0,0 +1,99 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Animation.pause()</title>
+<link rel="help" href="https://w3c.github.io/web-animations/#dom-animation-pause">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../testcommon.js"></script>
+<link rel="stylesheet" href="/resources/testharness.css">
+<body>
+<div id="log"></div>
+<script>
+"use strict";
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 1000 * MS_PER_SEC);
+ var previousCurrentTime = animation.currentTime;
+
+ return animation.ready.then(waitForAnimationFrames(1)).then(function() {
+ assert_true(animation.currentTime >= previousCurrentTime,
+ 'currentTime is initially increasing');
+ animation.pause();
+ return animation.ready;
+ }).then(function() {
+ previousCurrentTime = animation.currentTime;
+ return waitForAnimationFrames(1);
+ }).then(function() {
+ assert_equals(animation.currentTime, previousCurrentTime,
+ 'currentTime does not increase after calling pause()');
+ });
+}, 'pause() a running animation');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 1000 * MS_PER_SEC);
+
+ // Go to idle state then pause
+ animation.cancel();
+ animation.pause();
+
+ assert_equals(animation.currentTime, 0, 'currentTime is set to 0');
+ assert_equals(animation.startTime, null, 'startTime is not set');
+ assert_equals(animation.playState, 'pending', 'initially pause-pending');
+
+ // Check it still resolves as expected
+ return animation.ready.then(function() {
+ assert_equals(animation.playState, 'paused',
+ 'resolves to paused state asynchronously');
+ assert_equals(animation.currentTime, 0,
+ 'keeps the initially set currentTime');
+ });
+}, 'pause() from idle');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 1000 * MS_PER_SEC);
+ animation.cancel();
+ animation.playbackRate = -1;
+ animation.pause();
+
+ assert_equals(animation.currentTime, 1000 * MS_PER_SEC,
+ 'currentTime is set to the effect end');
+
+ return animation.ready.then(function() {
+ assert_equals(animation.currentTime, 1000 * MS_PER_SEC,
+ 'keeps the initially set currentTime');
+ });
+}, 'pause() from idle with a negative playbackRate');
+
+test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, {duration: 1000 * MS_PER_SEC,
+ iterations: Infinity});
+ animation.cancel();
+ animation.playbackRate = -1;
+
+ assert_throws('InvalidStateError',
+ function () { animation.pause(); },
+ 'Expect InvalidStateError exception on calling pause() ' +
+ 'from idle with a negative playbackRate and ' +
+ 'infinite-duration animation');
+}, 'pause() from idle with a negative playbackRate and endless effect');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 1000 * MS_PER_SEC);
+ return animation.ready
+ .then(function(animation) {
+ animation.finish();
+ animation.pause();
+ return animation.ready;
+ }).then(function(animation) {
+ assert_equals(animation.currentTime, 1000 * MS_PER_SEC,
+ 'currentTime after pausing finished animation');
+ });
+}, 'pause() on a finished animation');
+
+</script>
+</body>
diff --git a/tests/wpt/web-platform-tests/web-animations/animation/ready.html b/tests/wpt/web-platform-tests/web-animations/animation/ready.html
new file mode 100644
index 00000000000..cea946c1429
--- /dev/null
+++ b/tests/wpt/web-platform-tests/web-animations/animation/ready.html
@@ -0,0 +1,97 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Animation.ready</title>
+<link rel="help" href="https://w3c.github.io/web-animations/#dom-animation-ready">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../testcommon.js"></script>
+<link rel="stylesheet" href="/resources/testharness.css">
+<body>
+<div id="log"></div>
+<script>
+"use strict";
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+ var originalReadyPromise = animation.ready;
+ var pauseReadyPromise;
+
+ return animation.ready.then(function() {
+ assert_equals(animation.ready, originalReadyPromise,
+ 'Ready promise is the same object when playing completes');
+ animation.pause();
+ assert_not_equals(animation.ready, originalReadyPromise,
+ 'A new ready promise is created when pausing');
+ pauseReadyPromise = animation.ready;
+ // Wait for the promise to fulfill since if we abort the pause the ready
+ // promise object is reused.
+ return animation.ready;
+ }).then(function() {
+ animation.play();
+ assert_not_equals(animation.ready, pauseReadyPromise,
+ 'A new ready promise is created when playing');
+ });
+}, 'A new ready promise is created when play()/pause() is called');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+
+ return animation.ready.then(function() {
+ var promiseBeforeCallingPlay = animation.ready;
+ animation.play();
+ assert_equals(animation.ready, promiseBeforeCallingPlay,
+ 'Ready promise has same object identity after redundant call'
+ + ' to play()');
+ });
+}, 'Redundant calls to play() do not generate new ready promise objects');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+
+ return animation.ready.then(function(resolvedAnimation) {
+ assert_equals(resolvedAnimation, animation,
+ 'Object identity of Animation passed to Promise callback'
+ + ' matches the Animation object owning the Promise');
+ });
+}, 'The ready promise is fulfilled with its Animation');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+
+ var retPromise = animation.ready.then(function() {
+ assert_unreached('ready promise was fulfilled');
+ }).catch(function(err) {
+ assert_equals(err.name, 'AbortError',
+ 'ready promise is rejected with AbortError');
+ });
+
+ animation.cancel();
+
+ return retPromise;
+}, 'ready promise is rejected when a pause-pending animation is cancelled by'
+ + ' calling cancel()');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+ return animation.ready.then(function() {
+ animation.pause();
+ // Set up listeners on pause-pending ready promise
+ var retPromise = animation.ready.then(function() {
+ assert_unreached('ready promise was fulfilled');
+ }).catch(function(err) {
+ assert_equals(err.name, 'AbortError',
+ 'ready promise is rejected with AbortError');
+ });
+ animation.cancel();
+ return retPromise;
+ });
+}, 'ready promise is rejected when a pause-pending animation is cancelled by'
+ + ' calling cancel()');
+
+</script>
+</body>
diff --git a/tests/wpt/web-platform-tests/web-animations/animation/reverse.html b/tests/wpt/web-platform-tests/web-animations/animation/reverse.html
new file mode 100644
index 00000000000..3731cf51804
--- /dev/null
+++ b/tests/wpt/web-platform-tests/web-animations/animation/reverse.html
@@ -0,0 +1,150 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Animation.reverse()</title>
+<link rel="help" href="https://w3c.github.io/web-animations/#dom-animation-reverse">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../testcommon.js"></script>
+<link rel="stylesheet" href="/resources/testharness.css">
+<body>
+<div id="log"></div>
+<script>
+"use strict";
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, {duration: 100 * MS_PER_SEC,
+ iterations: Infinity});
+
+ // Wait a frame because if currentTime is still 0 when we call
+ // reverse(), it will throw (per spec).
+ return animation.ready.then(waitForAnimationFrames(1)).then(function() {
+ assert_greater_than_equal(animation.currentTime, 0,
+ 'currentTime expected to be greater than 0, one frame after starting');
+ animation.currentTime = 50 * MS_PER_SEC;
+ var previousPlaybackRate = animation.playbackRate;
+ animation.reverse();
+ assert_equals(animation.playbackRate, -previousPlaybackRate,
+ 'playbackRate should be inverted');
+ });
+}, 'reverse() inverts playbackRate');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, {duration: 100 * MS_PER_SEC,
+ iterations: Infinity});
+ animation.currentTime = 50 * MS_PER_SEC;
+ animation.pause();
+
+ return animation.ready.then(function() {
+ animation.reverse();
+ return animation.ready;
+ }).then(function() {
+ assert_equals(animation.playState, 'running',
+ 'Animation.playState should be "running" after reverse()');
+ });
+}, 'reverse() starts to play when pausing animation');
+
+test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+ animation.currentTime = 50 * MS_PER_SEC;
+ animation.reverse();
+
+ assert_equals(animation.currentTime, 50 * MS_PER_SEC,
+ 'reverse() should not change the currentTime ' +
+ 'if the currentTime is in the middle of animation duration');
+}, 'reverse() maintains the same currentTime');
+
+test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+ animation.currentTime = 200 * MS_PER_SEC;
+ animation.reverse();
+
+ assert_equals(animation.currentTime, 100 * MS_PER_SEC,
+ 'reverse() should start playing from the animation effect end ' +
+ 'if the playbackRate > 0 and the currentTime > effect end');
+}, 'reverse() when playbackRate > 0 and currentTime > effect end');
+
+test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+
+ animation.currentTime = -200 * MS_PER_SEC;
+ animation.reverse();
+
+ assert_equals(animation.currentTime, 100 * MS_PER_SEC,
+ 'reverse() should start playing from the animation effect end ' +
+ 'if the playbackRate > 0 and the currentTime < 0');
+}, 'reverse() when playbackRate > 0 and currentTime < 0');
+
+test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+ animation.playbackRate = -1;
+ animation.currentTime = -200 * MS_PER_SEC;
+ animation.reverse();
+
+ assert_equals(animation.currentTime, 0,
+ 'reverse() should start playing from the start of animation time ' +
+ 'if the playbackRate < 0 and the currentTime < 0');
+}, 'reverse() when playbackRate < 0 and currentTime < 0');
+
+test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+ animation.playbackRate = -1;
+ animation.currentTime = 200 * MS_PER_SEC;
+ animation.reverse();
+
+ assert_equals(animation.currentTime, 0,
+ 'reverse() should start playing from the start of animation time ' +
+ 'if the playbackRate < 0 and the currentTime > effect end');
+}, 'reverse() when playbackRate < 0 and currentTime > effect end');
+
+test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, {duration: 100 * MS_PER_SEC,
+ iterations: Infinity});
+ animation.currentTime = -200 * MS_PER_SEC;
+
+ assert_throws('InvalidStateError',
+ function () { animation.reverse(); },
+ 'reverse() should throw InvalidStateError ' +
+ 'if the playbackRate > 0 and the currentTime < 0 ' +
+ 'and the target effect is positive infinity');
+}, 'reverse() when playbackRate > 0 and currentTime < 0 ' +
+ 'and the target effect end is positive infinity');
+
+test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, {duration: 100 * MS_PER_SEC,
+ iterations: Infinity});
+ animation.playbackRate = -1;
+ animation.currentTime = -200 * MS_PER_SEC;
+ animation.reverse();
+
+ assert_equals(animation.currentTime, 0,
+ 'reverse() should start playing from the start of animation time ' +
+ 'if the playbackRate < 0 and the currentTime < 0 ' +
+ 'and the target effect is positive infinity');
+}, 'reverse() when playbackRate < 0 and currentTime < 0 ' +
+ 'and the target effect end is positive infinity');
+
+test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+ animation.playbackRate = 0;
+ animation.currentTime = 50 * MS_PER_SEC;
+ animation.reverse();
+
+ assert_equals(animation.playbackRate, 0,
+ 'reverse() should preserve playbackRate if the playbackRate == 0');
+ assert_equals(animation.currentTime, 50 * MS_PER_SEC,
+ 'reverse() should not affect the currentTime if the playbackRate == 0');
+ t.done();
+}, 'reverse() when playbackRate == 0');
+
+</script>
+</body>
diff --git a/tests/wpt/web-platform-tests/web-animations/keyframe-effect/constructor.html b/tests/wpt/web-platform-tests/web-animations/keyframe-effect/constructor.html
index 50cee72ac47..c14d74fa994 100644
--- a/tests/wpt/web-platform-tests/web-animations/keyframe-effect/constructor.html
+++ b/tests/wpt/web-platform-tests/web-animations/keyframe-effect/constructor.html
@@ -37,17 +37,6 @@ function assert_frame_lists_equal(a, b) {
var gEmptyKeyframeListTests = [
[],
- [{}],
- [{ easing: "ease-in" }],
- [{ unknown: "unknown" }, { unknown: "unknown" }],
- [{ color: "invalid" }, { color: "invalid" }],
- { easing: "ease-in" },
- { unknown: "unknown" },
- { unknown: [] },
- { unknown: ["unknown"] },
- { unknown: ["unknown", "unknown"] },
- { animationName: ["none", "abc"] },
- { color: [] },
null,
undefined,
];
@@ -79,7 +68,7 @@ test(function(t) {
"resulting easing for '" + easing + "'");
});
}, "easing values are parsed correctly when passed to the " +
- "KeyframeEffectReadOnly constructor in PropertyIndexedKeyframes");
+ "KeyframeEffectReadOnly constructor in a property-indexed keyframe");
test(function(t) {
gEasingValueTests.forEach(function(subtest) {
@@ -93,7 +82,7 @@ test(function(t) {
"resulting easing for '" + easing + "'");
});
}, "easing values are parsed correctly when passed to the " +
- "KeyframeEffectReadOnly constructor in Keyframe");
+ "KeyframeEffectReadOnly constructor in regular keyframes");
test(function(t) {
gEasingValueTests.forEach(function(subtest) {
@@ -135,7 +124,7 @@ test(function(t) {
});
});
}, "composite values are parsed correctly when passed to the " +
- "KeyframeEffectReadOnly constructor in PropertyIndexedKeyframes");
+ "KeyframeEffectReadOnly constructor in property-indexed keyframes");
test(function(t) {
var getFrames = function(composite) {
@@ -155,7 +144,7 @@ test(function(t) {
});
});
}, "composite values are parsed correctly when passed to the " +
- "KeyframeEffectReadOnly constructor in Keyframe");
+ "KeyframeEffectReadOnly constructor in regular keyframes");
test(function(t) {
gGoodOptionsCompositeValueTests.forEach(function(composite) {
@@ -176,79 +165,119 @@ test(function(t) {
"KeyframeEffectReadOnly constructor in KeyframeTimingOptions");
var gPropertyIndexedKeyframesTests = [
- { desc: "a one property two value PropertyIndexedKeyframes specification",
+ { desc: "a one property two value property-indexed keyframes specification",
input: { left: ["10px", "20px"] },
- output: [{ offset: 0, computedOffset: 0, easing: "linear", left: "10px" },
- { offset: 1, computedOffset: 1, easing: "linear", left: "20px" }] },
- { desc: "a one shorthand property two value PropertyIndexedKeyframes specification",
+ output: [{ offset: null, computedOffset: 0, easing: "linear",
+ left: "10px" },
+ { offset: null, computedOffset: 1, easing: "linear",
+ left: "20px" }] },
+ { desc: "a one shorthand property two value property-indexed keyframes"
+ + " specification",
input: { margin: ["10px", "10px 20px 30px 40px"] },
- output: [{ offset: 0, computedOffset: 0, easing: "linear", marginTop: "10px", marginRight: "10px", marginBottom: "10px", marginLeft: "10px" },
- { offset: 1, computedOffset: 1, easing: "linear", marginTop: "10px", marginRight: "20px", marginBottom: "30px", marginLeft: "40px" }] },
- { desc: "a two property (one shorthand and one of its longhand components) two value PropertyIndexedKeyframes specification",
+ output: [{ offset: null, computedOffset: 0, easing: "linear",
+ margin: "10px" },
+ { offset: null, computedOffset: 1, easing: "linear",
+ margin: "10px 20px 30px 40px" }] },
+ { desc: "a two property (one shorthand and one of its longhand components)"
+ + " two value property-indexed keyframes specification",
input: { marginTop: ["50px", "60px"],
margin: ["10px", "10px 20px 30px 40px"] },
- output: [{ offset: 0, computedOffset: 0, easing: "linear", marginTop: "50px", marginRight: "10px", marginBottom: "10px", marginLeft: "10px" },
- { offset: 1, computedOffset: 1, easing: "linear", marginTop: "60px", marginRight: "20px", marginBottom: "30px", marginLeft: "40px" }] },
- { desc: "a two property two value PropertyIndexedKeyframes specification",
+ output: [{ offset: null, computedOffset: 0, easing: "linear",
+ marginTop: "50px", margin: "10px" },
+ { offset: null, computedOffset: 1, easing: "linear",
+ marginTop: "60px", margin: "10px 20px 30px 40px" }] },
+ { desc: "a two property two value property-indexed keyframes specification",
input: { left: ["10px", "20px"],
top: ["30px", "40px"] },
- output: [{ offset: 0, computedOffset: 0, easing: "linear", left: "10px", top: "30px" },
- { offset: 1, computedOffset: 1, easing: "linear", left: "20px", top: "40px" }] },
- { desc: "a two property PropertyIndexedKeyframes specification with different numbers of values",
+ output: [{ offset: null, computedOffset: 0, easing: "linear",
+ left: "10px", top: "30px" },
+ { offset: null, computedOffset: 1, easing: "linear",
+ left: "20px", top: "40px" }] },
+ { desc: "a two property property-indexed keyframes specification with"
+ + " different numbers of values",
input: { left: ["10px", "20px", "30px"],
top: ["40px", "50px"] },
- output: [{ offset: 0.0, computedOffset: 0.0, easing: "linear", left: "10px", top: "40px" },
- { offset: 0.5, computedOffset: 0.5, easing: "linear", left: "20px" },
- { offset: 1.0, computedOffset: 1.0, easing: "linear", left: "30px", top: "50px" }] },
- { desc: "a PropertyIndexedKeyframes specification with an invalid value",
+ output: [{ offset: null, computedOffset: 0.0, easing: "linear",
+ left: "10px", top: "40px" },
+ { offset: null, computedOffset: 0.5, easing: "linear",
+ left: "20px" },
+ { offset: null, computedOffset: 1.0, easing: "linear",
+ left: "30px", top: "50px" }] },
+ { desc: "a property-indexed keyframes specification with an invalid value",
input: { left: ["10px", "20px", "30px", "40px", "50px"],
top: ["15px", "25px", "invalid", "45px", "55px"] },
- output: [{ offset: 0.00, computedOffset: 0.00, easing: "linear", left: "10px", top: "15px" },
- { offset: 0.25, computedOffset: 0.25, easing: "linear", left: "20px", top: "25px" },
- { offset: 0.50, computedOffset: 0.50, easing: "linear", left: "30px" },
- { offset: 0.75, computedOffset: 0.75, easing: "linear", left: "40px", top: "45px" },
- { offset: 1.00, computedOffset: 1.00, easing: "linear", left: "50px", top: "55px" }] },
- { desc: "a one property two value PropertyIndexedKeyframes specification that needs to stringify its values",
+ output: [{ offset: null, computedOffset: 0.00, easing: "linear",
+ left: "10px", top: "15px" },
+ { offset: null, computedOffset: 0.25, easing: "linear",
+ left: "20px", top: "25px" },
+ { offset: null, computedOffset: 0.50, easing: "linear",
+ left: "30px", top: "invalid" },
+ { offset: null, computedOffset: 0.75, easing: "linear",
+ left: "40px", top: "45px" },
+ { offset: null, computedOffset: 1.00, easing: "linear",
+ left: "50px", top: "55px" }] },
+ { desc: "a one property two value property-indexed keyframes specification"
+ + " that needs to stringify its values",
input: { opacity: [0, 1] },
- output: [{ offset: 0, computedOffset: 0, easing: "linear", opacity: "0" },
- { offset: 1, computedOffset: 1, easing: "linear", opacity: "1" }] },
- { desc: "a one property one value PropertyIndexedKeyframes specification",
+ output: [{ offset: null, computedOffset: 0, easing: "linear",
+ opacity: "0" },
+ { offset: null, computedOffset: 1, easing: "linear",
+ opacity: "1" }] },
+ { desc: "a one property one value property-indexed keyframes specification",
input: { left: ["10px"] },
- output: [{ offset: 0, computedOffset: 0, easing: "linear" },
- { offset: 1, computedOffset: 1, easing: "linear", left: "10px" }] },
- { desc: "a one property one non-array value PropertyIndexedKeyframes specification",
+ output: [{ offset: null, computedOffset: 1, easing: "linear",
+ left: "10px" }] },
+ { desc: "a one property one non-array value property-indexed keyframes"
+ + " specification",
input: { left: "10px" },
- output: [{ offset: 0, computedOffset: 0, easing: "linear" },
- { offset: 1, computedOffset: 1, easing: "linear", left: "10px" }] },
- { desc: "a one property two value PropertyIndexedKeyframes specification where the first value is invalid",
+ output: [{ offset: null, computedOffset: 1, easing: "linear",
+ left: "10px" }] },
+ { desc: "a one property two value property-indexed keyframes specification"
+ + " where the first value is invalid",
input: { left: ["invalid", "10px"] },
- output: [{ offset: 0, computedOffset: 0, easing: "linear" },
- { offset: 1, computedOffset: 1, easing: "linear", left: "10px" }] },
- { desc: "a one property two value PropertyIndexedKeyframes specification where the second value is invalid",
+ output: [{ offset: null, computedOffset: 0, easing: "linear",
+ left: "invalid" },
+ { offset: null, computedOffset: 1, easing: "linear",
+ left: "10px" }] },
+ { desc: "a one property two value property-indexed keyframes specification"
+ + " where the second value is invalid",
input: { left: ["10px", "invalid"] },
- output: [{ offset: 0, computedOffset: 0, easing: "linear", left: "10px" },
- { offset: 1, computedOffset: 1, easing: "linear" }] },
- { desc: "a two property PropertyIndexedKeyframes specification where one property is missing from the first Keyframe",
+ output: [{ offset: null, computedOffset: 0, easing: "linear",
+ left: "10px" },
+ { offset: null, computedOffset: 1, easing: "linear",
+ left: "invalid" }] },
+ { desc: "a two property property-indexed keyframes specification where one"
+ + " property is missing from the first keyframe",
input: [{ offset: 0, left: "10px" },
{ offset: 1, left: "20px", top: "30px" }],
output: [{ offset: 0, computedOffset: 0, easing: "linear", left: "10px" },
- { offset: 1, computedOffset: 1, easing: "linear", left: "20px", top: "30px" }] },
- { desc: "a two property PropertyIndexedKeyframes specification where one property is missing from the last Keyframe",
+ { offset: 1, computedOffset: 1, easing: "linear",
+ left: "20px", top: "30px" }] },
+ { desc: "a two property property-indexed keyframes specification where one"
+ + " property is missing from the last keyframe",
input: [{ offset: 0, left: "10px", top: "20px" },
{ offset: 1, left: "30px" }],
- output: [{ offset: 0, computedOffset: 0, easing: "linear", left: "10px" , top: "20px" },
- { offset: 1, computedOffset: 1, easing: "linear", left: "30px" }] },
- { desc: "a PropertyIndexedKeyframes specification with repeated values at offset 0 with different easings",
+ output: [{ offset: 0, computedOffset: 0, easing: "linear",
+ left: "10px" , top: "20px" },
+ { offset: 1, computedOffset: 1, easing: "linear",
+ left: "30px" }] },
+ { desc: "a property-indexed keyframes specification with repeated values"
+ + " at offset 0 with different easings",
input: [{ offset: 0.0, left: "100px", easing: "ease" },
{ offset: 0.0, left: "200px", easing: "ease" },
{ offset: 0.5, left: "300px", easing: "linear" },
{ offset: 1.0, left: "400px", easing: "ease-out" },
{ offset: 1.0, left: "500px", easing: "step-end" }],
- output: [{ offset: 0.0, computedOffset: 0.0, easing: "ease", left: "100px" },
- { offset: 0.0, computedOffset: 0.0, easing: "ease", left: "200px" },
- { offset: 0.5, computedOffset: 0.5, easing: "linear", left: "300px" },
- { offset: 1.0, computedOffset: 1.0, easing: "ease-out", left: "400px" },
- { offset: 1.0, computedOffset: 1.0, easing: "linear", left: "500px" }] },
+ output: [{ offset: 0.0, computedOffset: 0.0, easing: "ease",
+ left: "100px" },
+ { offset: 0.0, computedOffset: 0.0, easing: "ease",
+ left: "200px" },
+ { offset: 0.5, computedOffset: 0.5, easing: "linear",
+ left: "300px" },
+ { offset: 1.0, computedOffset: 1.0, easing: "ease-out",
+ left: "400px" },
+ { offset: 1.0, computedOffset: 1.0, easing: "step-end",
+ left: "500px" }] },
];
gPropertyIndexedKeyframesTests.forEach(function(subtest) {
@@ -282,41 +311,56 @@ test(function(t) {
});
new KeyframeEffectReadOnly(target, [kf1, kf2]);
assert_array_equals(actualOrder, expectedOrder, "property access order");
-}, "the KeyframeEffectReadOnly constructor reads Keyframe properties in the " +
+}, "the KeyframeEffectReadOnly constructor reads keyframe properties in the " +
"expected order");
var gKeyframeSequenceTests = [
- { desc: "a one property two Keyframe sequence",
+ { desc: "a one property two keyframe sequence",
input: [{ offset: 0, left: "10px" },
{ offset: 1, left: "20px" }],
output: [{ offset: 0, computedOffset: 0, easing: "linear", left: "10px" },
- { offset: 1, computedOffset: 1, easing: "linear", left: "20px" }] },
- { desc: "a two property two Keyframe sequence",
+ { offset: 1, computedOffset: 1, easing: "linear", left: "20px" }]
+ },
+ { desc: "a two property two keyframe sequence",
input: [{ offset: 0, left: "10px", top: "30px" },
{ offset: 1, left: "20px", top: "40px" }],
- output: [{ offset: 0, computedOffset: 0, easing: "linear", left: "10px", top: "30px" },
- { offset: 1, computedOffset: 1, easing: "linear", left: "20px", top: "40px" }] },
- { desc: "a one shorthand property two Keyframe sequence",
+ output: [{ offset: 0, computedOffset: 0, easing: "linear",
+ left: "10px", top: "30px" },
+ { offset: 1, computedOffset: 1, easing: "linear",
+ left: "20px", top: "40px" }] },
+ { desc: "a one shorthand property two keyframe sequence",
input: [{ offset: 0, margin: "10px" },
{ offset: 1, margin: "20px 30px 40px 50px" }],
- output: [{ offset: 0, computedOffset: 0, easing: "linear", marginTop: "10px", marginRight: "10px", marginBottom: "10px", marginLeft: "10px" },
- { offset: 1, computedOffset: 1, easing: "linear", marginTop: "20px", marginRight: "30px", marginBottom: "40px", marginLeft: "50px" }] },
- { desc: "a two property (a shorthand and one of its component longhands) two Keyframe sequence",
+ output: [{ offset: 0, computedOffset: 0, easing: "linear",
+ margin: "10px" },
+ { offset: 1, computedOffset: 1, easing: "linear",
+ margin: "20px 30px 40px 50px" }] },
+ { desc: "a two property (a shorthand and one of its component longhands)"
+ + " two keyframe sequence",
input: [{ offset: 0, margin: "10px", marginTop: "20px" },
{ offset: 1, marginTop: "70px", margin: "30px 40px 50px 60px" }],
- output: [{ offset: 0, computedOffset: 0, easing: "linear", marginTop: "20px", marginRight: "10px", marginBottom: "10px", marginLeft: "10px" },
- { offset: 1, computedOffset: 1, easing: "linear", marginTop: "70px", marginRight: "40px", marginBottom: "50px", marginLeft: "60px" }] },
- { desc: "a Keyframe sequence with duplicate values for a given interior offset",
+ output: [{ offset: 0, computedOffset: 0, easing: "linear",
+ margin: "10px", marginTop: "20px" },
+ { offset: 1, computedOffset: 1, easing: "linear",
+ marginTop: "70px", margin: "30px 40px 50px 60px" }] },
+ { desc: "a keyframe sequence with duplicate values for a given interior"
+ + " offset",
input: [{ offset: 0.0, left: "10px" },
{ offset: 0.5, left: "20px" },
{ offset: 0.5, left: "30px" },
{ offset: 0.5, left: "40px" },
{ offset: 1.0, left: "50px" }],
- output: [{ offset: 0.0, computedOffset: 0.0, easing: "linear", left: "10px" },
- { offset: 0.5, computedOffset: 0.5, easing: "linear", left: "20px" },
- { offset: 0.5, computedOffset: 0.5, easing: "linear", left: "40px" },
- { offset: 1.0, computedOffset: 1.0, easing: "linear", left: "50px" }] },
- { desc: "a Keyframe sequence with duplicate values for offsets 0 and 1",
+ output: [{ offset: 0.0, computedOffset: 0.0, easing: "linear",
+ left: "10px" },
+ { offset: 0.5, computedOffset: 0.5, easing: "linear",
+ left: "20px" },
+ { offset: 0.5, computedOffset: 0.5, easing: "linear",
+ left: "30px" },
+ { offset: 0.5, computedOffset: 0.5, easing: "linear",
+ left: "40px" },
+ { offset: 1.0, computedOffset: 1.0, easing: "linear",
+ left: "50px" }] },
+ { desc: "a keyframe sequence with duplicate values for offsets 0 and 1",
input: [{ offset: 0, left: "10px" },
{ offset: 0, left: "20px" },
{ offset: 0, left: "30px" },
@@ -324,50 +368,72 @@ var gKeyframeSequenceTests = [
{ offset: 1, left: "50px" },
{ offset: 1, left: "60px" }],
output: [{ offset: 0, computedOffset: 0, easing: "linear", left: "10px" },
+ { offset: 0, computedOffset: 0, easing: "linear", left: "20px" },
{ offset: 0, computedOffset: 0, easing: "linear", left: "30px" },
{ offset: 1, computedOffset: 1, easing: "linear", left: "40px" },
- { offset: 1, computedOffset: 1, easing: "linear", left: "60px" }] },
- { desc: "a two property four Keyframe sequence",
+ { offset: 1, computedOffset: 1, easing: "linear", left: "50px" },
+ { offset: 1, computedOffset: 1, easing: "linear", left: "60px" }]
+ },
+ { desc: "a two property four keyframe sequence",
input: [{ offset: 0, left: "10px" },
{ offset: 0, top: "20px" },
{ offset: 1, top: "30px" },
{ offset: 1, left: "40px" }],
- output: [{ offset: 0, computedOffset: 0, easing: "linear", left: "10px", top: "20px" },
- { offset: 1, computedOffset: 1, easing: "linear", left: "40px", top: "30px" }] },
- { desc: "a one property Keyframe sequence with some omitted offsets",
+ output: [{ offset: 0, computedOffset: 0, easing: "linear", left: "10px" },
+ { offset: 0, computedOffset: 0, easing: "linear", top: "20px" },
+ { offset: 1, computedOffset: 1, easing: "linear", top: "30px" },
+ { offset: 1, computedOffset: 1, easing: "linear", left: "40px" }]
+ },
+ { desc: "a one property keyframe sequence with some omitted offsets",
input: [{ offset: 0.00, left: "10px" },
{ offset: 0.25, left: "20px" },
{ left: "30px" },
{ left: "40px" },
{ offset: 1.00, left: "50px" }],
- output: [{ offset: 0.00, computedOffset: 0.00, easing: "linear", left: "10px" },
- { offset: 0.25, computedOffset: 0.25, easing: "linear", left: "20px" },
- { offset: 0.50, computedOffset: 0.50, easing: "linear", left: "30px" },
- { offset: 0.75, computedOffset: 0.75, easing: "linear", left: "40px" },
- { offset: 1.00, computedOffset: 1.00, easing: "linear", left: "50px" }] },
- { desc: "a two property Keyframe sequence with some omitted offsets",
+ output: [{ offset: 0.00, computedOffset: 0.00, easing: "linear",
+ left: "10px" },
+ { offset: 0.25, computedOffset: 0.25, easing: "linear",
+ left: "20px" },
+ { offset: null, computedOffset: 0.50, easing: "linear",
+ left: "30px" },
+ { offset: null, computedOffset: 0.75, easing: "linear",
+ left: "40px" },
+ { offset: 1.00, computedOffset: 1.00, easing: "linear",
+ left: "50px" }] },
+ { desc: "a two property keyframe sequence with some omitted offsets",
input: [{ offset: 0.00, left: "10px", top: "20px" },
{ offset: 0.25, left: "30px" },
{ left: "40px" },
{ left: "50px", top: "60px" },
{ offset: 1.00, left: "70px", top: "80px" }],
- output: [{ offset: 0.00, computedOffset: 0.00, easing: "linear", left: "10px", top: "20px" },
- { offset: 0.25, computedOffset: 0.25, easing: "linear", left: "30px" },
- { offset: 0.50, computedOffset: 0.50, easing: "linear", left: "40px" },
- { offset: 0.75, computedOffset: 0.75, easing: "linear", left: "50px", top: "60px" },
- { offset: 1.00, computedOffset: 1.00, easing: "linear", left: "70px", top: "80px" }] },
- { desc: "a one property Keyframe sequence with all omitted offsets",
+ output: [{ offset: 0.00, computedOffset: 0.00, easing: "linear",
+ left: "10px", top: "20px" },
+ { offset: 0.25, computedOffset: 0.25, easing: "linear",
+ left: "30px" },
+ { offset: null, computedOffset: 0.50, easing: "linear",
+ left: "40px" },
+ { offset: null, computedOffset: 0.75, easing: "linear",
+ left: "50px", top: "60px" },
+ { offset: 1.00, computedOffset: 1.00, easing: "linear",
+ left: "70px", top: "80px" }] },
+ { desc: "a one property keyframe sequence with all omitted offsets",
input: [{ left: "10px" },
{ left: "20px" },
{ left: "30px" },
{ left: "40px" },
{ left: "50px" }],
- output: [{ offset: 0.00, computedOffset: 0.00, easing: "linear", left: "10px" },
- { offset: 0.25, computedOffset: 0.25, easing: "linear", left: "20px" },
- { offset: 0.50, computedOffset: 0.50, easing: "linear", left: "30px" },
- { offset: 0.75, computedOffset: 0.75, easing: "linear", left: "40px" },
- { offset: 1.00, computedOffset: 1.00, easing: "linear", left: "50px" }] },
- { desc: "a Keyframe sequence with different easing values, but the same easing value for a given offset",
+ output: [{ offset: null, computedOffset: 0.00, easing: "linear",
+ left: "10px" },
+ { offset: null, computedOffset: 0.25, easing: "linear",
+ left: "20px" },
+ { offset: null, computedOffset: 0.50, easing: "linear",
+ left: "30px" },
+ { offset: null, computedOffset: 0.75, easing: "linear",
+ left: "40px" },
+ { offset: null, computedOffset: 1.00, easing: "linear",
+ left: "50px" }] },
+ { desc: "a keyframe sequence with different easing values, but the same"
+ + " easing value for a given offset",
input: [{ offset: 0.0, easing: "ease", left: "10px"},
{ offset: 0.0, easing: "ease", top: "20px"},
{ offset: 0.5, easing: "linear", left: "30px" },
@@ -375,62 +441,79 @@ var gKeyframeSequenceTests = [
{ offset: 1.0, easing: "step-end", left: "50px" },
{ offset: 1.0, easing: "step-end", top: "60px" }],
output: [{ offset: 0.0, computedOffset: 0.0, easing: "ease",
- left: "10px", top: "20px" },
+ left: "10px" },
+ { offset: 0.0, computedOffset: 0.0, easing: "ease",
+ top: "20px" },
{ offset: 0.5, computedOffset: 0.5, easing: "linear",
- left: "30px", top: "40px" },
- { offset: 1.0, computedOffset: 1.0, easing: "linear",
- left: "50px", top: "60px" }] },
- { desc: "a Keyframe sequence with different composite values, but the same composite value for a given offset",
+ left: "30px" },
+ { offset: 0.5, computedOffset: 0.5, easing: "linear",
+ top: "40px" },
+ { offset: 1.0, computedOffset: 1.0, easing: "step-end",
+ left: "50px" },
+ { offset: 1.0, computedOffset: 1.0, easing: "step-end",
+ top: "60px" }] },
+ { desc: "a keyframe sequence with different composite values, but the"
+ + " same composite value for a given offset",
input: [{ offset: 0.0, composite: "replace", left: "10px" },
{ offset: 0.0, composite: "replace", top: "20px" },
{ offset: 0.5, composite: "add", left: "30px" },
{ offset: 0.5, composite: "add", top: "40px" },
{ offset: 1.0, composite: "replace", left: "50px" },
{ offset: 1.0, composite: "replace", top: "60px" }],
- output: [{ offset: 0.0, computedOffset: 0.0, easing: "linear", composite: "replace", left: "10px", top: "20px" },
- { offset: 0.5, computedOffset: 0.5, easing: "linear", composite: "add", left: "30px", top: "40px" },
- { offset: 1.0, computedOffset: 1.0, easing: "linear", composite: "replace", left: "50px", top: "60px" }] },
- { desc: "a one property two Keyframe sequence that needs to stringify its values",
+ output: [{ offset: 0.0, computedOffset: 0.0, easing: "linear",
+ composite: "replace", left: "10px" },
+ { offset: 0.0, computedOffset: 0.0, easing: "linear",
+ composite: "replace", top: "20px" },
+ { offset: 0.5, computedOffset: 0.0, easing: "linear",
+ composite: "add", left: "30px" },
+ { offset: 0.5, computedOffset: 0.0, easing: "linear",
+ composite: "add", top: "40px" },
+ { offset: 1.0, computedOffset: 1.0, easing: "linear",
+ composite: "replace", left: "50px" },
+ { offset: 1.0, computedOffset: 1.0, easing: "linear",
+ composite: "replace", top: "60px" }] },
+ { desc: "a one property two keyframe sequence that needs to stringify"
+ + " its values",
input: [{ offset: 0, opacity: 0 },
{ offset: 1, opacity: 1 }],
output: [{ offset: 0, computedOffset: 0, easing: "linear", opacity: "0" },
- { offset: 1, computedOffset: 1, easing: "linear", opacity: "1" }] },
- { desc: "a Keyframe sequence where shorthand precedes longhand",
+ { offset: 1, computedOffset: 1, easing: "linear", opacity: "1" }]
+ },
+ { desc: "a keyframe sequence where shorthand precedes longhand",
input: [{ offset: 0, margin: "10px", marginRight: "20px" },
{ offset: 1, margin: "30px" }],
- output: [{ offset: 0, computedOffset: 0, easing: "linear", marginBottom: "10px", marginLeft: "10px", marginRight: "20px", marginTop: "10px" },
- { offset: 1, computedOffset: 1, easing: "linear", marginBottom: "30px", marginLeft: "30px", marginRight: "30px", marginTop: "30px" }] },
- { desc: "a Keyframe sequence where longhand precedes shorthand",
+ output: [{ offset: 0, computedOffset: 0, easing: "linear",
+ margin: "10px", marginRight: "20px" },
+ { offset: 1, computedOffset: 1, easing: "linear",
+ margin: "30px" }] },
+ { desc: "a keyframe sequence where longhand precedes shorthand",
input: [{ offset: 0, marginRight: "20px", margin: "10px" },
{ offset: 1, margin: "30px" }],
- output: [{ offset: 0, computedOffset: 0, easing: "linear", marginBottom: "10px", marginLeft: "10px", marginRight: "20px", marginTop: "10px" },
- { offset: 1, computedOffset: 1, easing: "linear", marginBottom: "30px", marginLeft: "30px", marginRight: "30px", marginTop: "30px" }] },
- { desc: "a Keyframe sequence where lesser shorthand precedes greater shorthand",
- input: [{ offset: 0, borderLeft: "1px solid rgb(1, 2, 3)", border: "2px dotted rgb(4, 5, 6)" },
+ output: [{ offset: 0, computedOffset: 0, easing: "linear",
+ marginRight: "20px", margin: "10px" },
+ { offset: 1, computedOffset: 1, easing: "linear",
+ margin: "30px" }] },
+ { desc: "a keyframe sequence where lesser shorthand precedes greater"
+ + " shorthand",
+ input: [{ offset: 0,
+ borderLeft: "1px solid rgb(1, 2, 3)",
+ border: "2px dotted rgb(4, 5, 6)" },
{ offset: 1, border: "3px dashed rgb(7, 8, 9)" }],
output: [{ offset: 0, computedOffset: 0, easing: "linear",
- borderBottomColor: "rgb(4, 5, 6)", borderBottomWidth: "2px",
- borderLeftColor: "rgb(1, 2, 3)", borderLeftWidth: "1px",
- borderRightColor: "rgb(4, 5, 6)", borderRightWidth: "2px",
- borderTopColor: "rgb(4, 5, 6)", borderTopWidth: "2px" },
+ borderLeft: "1px solid rgb(1, 2, 3)",
+ border: "2px dotted rgb(4, 5, 6)" },
{ offset: 1, computedOffset: 1, easing: "linear",
- borderBottomColor: "rgb(7, 8, 9)", borderBottomWidth: "3px",
- borderLeftColor: "rgb(7, 8, 9)", borderLeftWidth: "3px",
- borderRightColor: "rgb(7, 8, 9)", borderRightWidth: "3px",
- borderTopColor: "rgb(7, 8, 9)", borderTopWidth: "3px" }] },
- { desc: "a Keyframe sequence where greater shorthand precedes lesser shorthand",
- input: [{ offset: 0, border: "2px dotted rgb(4, 5, 6)", borderLeft: "1px solid rgb(1, 2, 3)" },
+ border: "3px dashed rgb(7, 8, 9)" }] },
+ { desc: "a keyframe sequence where greater shorthand precedes lesser"
+ + " shorthand",
+ input: [{ offset: 0, border: "2px dotted rgb(4, 5, 6)",
+ borderLeft: "1px solid rgb(1, 2, 3)" },
{ offset: 1, border: "3px dashed rgb(7, 8, 9)" }],
output: [{ offset: 0, computedOffset: 0, easing: "linear",
- borderBottomColor: "rgb(4, 5, 6)", borderBottomWidth: "2px",
- borderLeftColor: "rgb(1, 2, 3)", borderLeftWidth: "1px",
- borderRightColor: "rgb(4, 5, 6)", borderRightWidth: "2px",
- borderTopColor: "rgb(4, 5, 6)", borderTopWidth: "2px" },
+ border: "2px dotted rgb(4, 5, 6)",
+ borderLeft: "1px solid rgb(1, 2, 3)" },
{ offset: 1, computedOffset: 1, easing: "linear",
- borderBottomColor: "rgb(7, 8, 9)", borderBottomWidth: "3px",
- borderLeftColor: "rgb(7, 8, 9)", borderLeftWidth: "3px",
- borderRightColor: "rgb(7, 8, 9)", borderRightWidth: "3px",
- borderTopColor: "rgb(7, 8, 9)", borderTopWidth: "3px" }] },
+ border: "3px dashed rgb(7, 8, 9)" }] },
];
gKeyframeSequenceTests.forEach(function(subtest) {
@@ -467,7 +550,7 @@ gInvalidEasingInKeyframeSequenceTests.forEach(function(subtest) {
assert_throws(new TypeError, function() {
new KeyframeEffectReadOnly(target, subtest.input);
});
- }, "Invalid easing [" + subtest.desc + "] in KeyframeSequence " +
+ }, "Invalid easing [" + subtest.desc + "] in keyframe sequence " +
"should be thrown");
});
diff --git a/tests/wpt/web-platform-tests/web-animations/keyframe-effect/effect-easing.html b/tests/wpt/web-platform-tests/web-animations/keyframe-effect/effect-easing.html
index 2ecd028ce9b..81e834e2e50 100644
--- a/tests/wpt/web-platform-tests/web-animations/keyframe-effect/effect-easing.html
+++ b/tests/wpt/web-platform-tests/web-animations/keyframe-effect/effect-easing.html
@@ -6,6 +6,7 @@
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../testcommon.js"></script>
+<script src="../resources/effect-easing-tests.js"></script>
<body>
<div id="log"></div>
<div id="target"></div>
@@ -22,54 +23,6 @@ function assert_style_left_at(animation, time, easingFunction) {
easingFunction(portion) * 100 + ' at ' + time + 'ms');
}
-var gEffectEasingTests = [
- {
- desc: 'steps(start) function',
- easing: 'steps(2, start)',
- easingFunction: stepStart(2)
- },
- {
- desc: 'steps(end) function',
- easing: 'steps(2, end)',
- easingFunction: stepEnd(2)
- },
- {
- desc: 'linear function',
- easing: 'linear', // cubic-bezier(0, 0, 1.0, 1.0)
- easingFunction: cubicBezier(0, 0, 1.0, 1.0)
- },
- {
- desc: 'ease function',
- easing: 'ease', // cubic-bezier(0.25, 0.1, 0.25, 1.0)
- easingFunction: cubicBezier(0.25, 0.1, 0.25, 1.0)
- },
- {
- desc: 'ease-in function',
- easing: 'ease-in', // cubic-bezier(0.42, 0, 1.0, 1.0)
- easingFunction: cubicBezier(0.42, 0, 1.0, 1.0)
- },
- {
- desc: 'ease-in-out function',
- easing: 'ease-in-out', // cubic-bezier(0.42, 0, 0.58, 1.0)
- easingFunction: cubicBezier(0.42, 0, 0.58, 1.0)
- },
- {
- desc: 'ease-out function',
- easing: 'ease-out', // cubic-bezier(0, 0, 0.58, 1.0)
- easingFunction: cubicBezier(0, 0, 0.58, 1.0)
- },
- {
- desc: 'easing function which produces values greater than 1',
- easing: 'cubic-bezier(0, 1.5, 1, 1.5)',
- easingFunction: cubicBezier(0, 1.5, 1, 1.5)
- },
- {
- desc: 'easing function which produces negative values',
- easing: 'cubic-bezier(0, -0.5 ,1, -0.5)',
- easingFunction: cubicBezier(0, -0.5, 1, -0.5)
- },
-];
-
gEffectEasingTests.forEach(function(options) {
test(function(t) {
var target = createDiv(t);
@@ -694,7 +647,7 @@ var gStepTimingFunctionTests = [
{ currentTime: 2500, progress: 0.5 },
]
}
-]
+];
gStepTimingFunctionTests.forEach(function(options) {
test(function(t) {
diff --git a/tests/wpt/web-platform-tests/web-animations/keyframe-effect/keyframe-handling.html b/tests/wpt/web-platform-tests/web-animations/keyframe-effect/keyframe-handling.html
index 56f484aff7f..de9b7c7ec21 100644
--- a/tests/wpt/web-platform-tests/web-animations/keyframe-effect/keyframe-handling.html
+++ b/tests/wpt/web-platform-tests/web-animations/keyframe-effect/keyframe-handling.html
@@ -70,6 +70,46 @@ test(function(t) {
}, 'Overlapping keyframes between 0 and 1 use the appropriate value on each'
+ ' side of the overlap point');
+test(function(t) {
+ var div = createDiv(t);
+ var anim = div.animate({ visibility: ['hidden','visible'] },
+ { duration: 100 * MS_PER_SEC, fill: 'both' });
+
+ anim.currentTime = 0;
+ assert_equals(getComputedStyle(div).visibility, 'hidden',
+ 'Visibility when progress = 0.');
+
+ anim.currentTime = 10 * MS_PER_SEC + 1;
+ assert_equals(getComputedStyle(div).visibility, 'visible',
+ 'Visibility when progress > 0 due to linear easing.');
+
+ anim.finish();
+ assert_equals(getComputedStyle(div).visibility, 'visible',
+ 'Visibility when progress = 1.');
+
+}, "Test visibility clamping behavior.");
+
+test(function(t) {
+ var div = createDiv(t);
+ var anim = div.animate({ visibility: ['hidden', 'visible'] },
+ { duration: 100 * MS_PER_SEC, fill: 'both',
+ easing: 'cubic-bezier(0.25, -0.6, 0, 0.5)' });
+
+ anim.currentTime = 0;
+ assert_equals(getComputedStyle(div).visibility, 'hidden',
+ 'Visibility when progress = 0.');
+
+ // Timing function is below zero. So we expected visibility is hidden.
+ anim.currentTime = 10 * MS_PER_SEC + 1;
+ assert_equals(getComputedStyle(div).visibility, 'hidden',
+ 'Visibility when progress < 0 due to cubic-bezier easing.');
+
+ anim.currentTime = 60 * MS_PER_SEC;
+ assert_equals(getComputedStyle(div).visibility, 'visible',
+ 'Visibility when progress > 0 due to cubic-bezier easing.');
+
+}, "Test visibility clamping behavior with an easing that has a negative component");
+
done();
</script>
</body>
diff --git a/tests/wpt/web-platform-tests/web-animations/resources/effect-easing-tests.js b/tests/wpt/web-platform-tests/web-animations/resources/effect-easing-tests.js
new file mode 100644
index 00000000000..edce67ede44
--- /dev/null
+++ b/tests/wpt/web-platform-tests/web-animations/resources/effect-easing-tests.js
@@ -0,0 +1,42 @@
+var gEffectEasingTests = [
+ {
+ desc: 'steps(start) function',
+ easing: 'steps(2, start)',
+ easingFunction: stepStart(2)
+ },
+ {
+ desc: 'steps(end) function',
+ easing: 'steps(2, end)',
+ easingFunction: stepEnd(2)
+ },
+ {
+ desc: 'linear function',
+ easing: 'linear', // cubic-bezier(0, 0, 1.0, 1.0)
+ easingFunction: cubicBezier(0, 0, 1.0, 1.0)
+ },
+ {
+ desc: 'ease function',
+ easing: 'ease', // cubic-bezier(0.25, 0.1, 0.25, 1.0)
+ easingFunction: cubicBezier(0.25, 0.1, 0.25, 1.0)
+ },
+ {
+ desc: 'ease-in function',
+ easing: 'ease-in', // cubic-bezier(0.42, 0, 1.0, 1.0)
+ easingFunction: cubicBezier(0.42, 0, 1.0, 1.0)
+ },
+ {
+ desc: 'ease-in-out function',
+ easing: 'ease-in-out', // cubic-bezier(0.42, 0, 0.58, 1.0)
+ easingFunction: cubicBezier(0.42, 0, 0.58, 1.0)
+ },
+ {
+ desc: 'ease-out function',
+ easing: 'ease-out', // cubic-bezier(0, 0, 0.58, 1.0)
+ easingFunction: cubicBezier(0, 0, 0.58, 1.0)
+ },
+ {
+ desc: 'easing function which produces values greater than 1',
+ easing: 'cubic-bezier(0, 1.5, 1, 1.5)',
+ easingFunction: cubicBezier(0, 1.5, 1, 1.5)
+ }
+];
diff --git a/tests/wpt/web-platform-tests/websockets/constructor/018.html b/tests/wpt/web-platform-tests/websockets/constructor/018.html
index 71359d0d093..4df953bf0be 100644
--- a/tests/wpt/web-platform-tests/websockets/constructor/018.html
+++ b/tests/wpt/web-platform-tests/websockets/constructor/018.html
@@ -6,9 +6,9 @@
<div id=log></div>
<script>
async_test(function(t) {
- var ws = new WebSocket(SCHEME_DOMAIN_PORT+'/echo-query?x\u0000');
+ var ws = new WebSocket(SCHEME_DOMAIN_PORT+'/echo-query?x\u0000y\u0000');
ws.onmessage = t.step_func(function(e) {
- assert_equals(e.data, 'x%00');
+ assert_equals(e.data, 'x%00y');
ws.close();
t.done();
})