diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2016-04-21 16:53:18 +0530 |
---|---|---|
committer | bors-servo <lbergstrom+bors@mozilla.com> | 2016-04-21 16:53:18 +0530 |
commit | 1eec5d9f7222dd3f7020b51e18ed6df3386b18f9 (patch) | |
tree | fc7ece0869b272c92aa036a9852eedc41bdd56cf /tests | |
parent | 7e370c4df4ee0c564322a0bebd34b31359e88d85 (diff) | |
parent | abcd4b654fd7a7adf493617bf6fe3b9ace15f6bb (diff) | |
download | servo-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')
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&reportField=violated-directive&reportValue=form-action%20'none'"></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&reportField=violated-directive&reportValue=form-action%20'none' "></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&reportField=violated-directive&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'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's a CSP report and "FAIL!" isn'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&reportField=violated-directive&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&reportField=violated-directive&reportValue=connect-src%20'self'"; + 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&reportField=violated-directive&reportValue=connect-src%20'self'"></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&reportField=violated-directive&reportValue=connect-src%20'self'"; + 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&reportField=violated-directive&reportValue=connect-src%20'self'"></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(); }) |