Unreviewed, rolling out r251536.
authorrepstein@apple.com <repstein@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 24 Oct 2019 23:45:01 +0000 (23:45 +0000)
committerrepstein@apple.com <repstein@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 24 Oct 2019 23:45:01 +0000 (23:45 +0000)
Landed 3 Broken Tests.

Reverted changeset:

"[Web Animations] Update WPT tests related to Web Animations
and remove imported Mozilla tests"
https://bugs.webkit.org/show_bug.cgi?id=203291
https://trac.webkit.org/changeset/251536

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@251573 268f45cc-cd09-0410-ab3c-d52691b4dbfc

422 files changed:
LayoutTests/ChangeLog
LayoutTests/TestExpectations
LayoutTests/imported/mozilla/ChangeLog
LayoutTests/imported/mozilla/css-animations/test_animation-cancel-expected.txt [new file with mode: 0644]
LayoutTests/imported/mozilla/css-animations/test_animation-cancel.html [new file with mode: 0644]
LayoutTests/imported/mozilla/css-animations/test_animation-computed-timing-expected.txt [moved from LayoutTests/imported/w3c/web-platform-tests/css/css-animations/AnimationEffect-getComputedTiming.tentative-expected.txt with 100% similarity]
LayoutTests/imported/mozilla/css-animations/test_animation-computed-timing.html [moved from LayoutTests/imported/w3c/web-platform-tests/css/css-animations/AnimationEffect-getComputedTiming.tentative.html with 67% similarity]
LayoutTests/imported/mozilla/css-animations/test_animation-currenttime-expected.txt [new file with mode: 0644]
LayoutTests/imported/mozilla/css-animations/test_animation-currenttime.html [new file with mode: 0644]
LayoutTests/imported/mozilla/css-animations/test_animation-finish-expected.txt [new file with mode: 0644]
LayoutTests/imported/mozilla/css-animations/test_animation-finish.html [new file with mode: 0644]
LayoutTests/imported/mozilla/css-animations/test_animation-finished-expected.txt [new file with mode: 0644]
LayoutTests/imported/mozilla/css-animations/test_animation-finished.html [new file with mode: 0644]
LayoutTests/imported/mozilla/css-animations/test_animation-id-expected.txt [moved from LayoutTests/imported/w3c/web-platform-tests/css/css-animations/CSSAnimation-id.tentative-expected.txt with 100% similarity]
LayoutTests/imported/mozilla/css-animations/test_animation-id.html [new file with mode: 0644]
LayoutTests/imported/mozilla/css-animations/test_animation-pausing-expected.txt [moved from LayoutTests/imported/w3c/web-platform-tests/css/css-animations/CSSAnimation-pausing.tentative-expected.txt with 100% similarity]
LayoutTests/imported/mozilla/css-animations/test_animation-pausing.html [new file with mode: 0644]
LayoutTests/imported/mozilla/css-animations/test_animation-playstate-expected.txt [moved from LayoutTests/imported/w3c/web-platform-tests/css/css-animations/CSSAnimation-playState.tentative-expected.txt with 61% similarity]
LayoutTests/imported/mozilla/css-animations/test_animation-playstate.html [new file with mode: 0644]
LayoutTests/imported/mozilla/css-animations/test_animation-ready-expected.txt [moved from LayoutTests/imported/w3c/web-platform-tests/css/css-animations/CSSAnimation-ready.tentative-expected.txt with 55% similarity]
LayoutTests/imported/mozilla/css-animations/test_animation-ready.html [new file with mode: 0644]
LayoutTests/imported/mozilla/css-animations/test_animation-reverse-expected.txt [new file with mode: 0644]
LayoutTests/imported/mozilla/css-animations/test_animation-reverse.html [new file with mode: 0644]
LayoutTests/imported/mozilla/css-animations/test_animation-starttime-expected.txt [new file with mode: 0644]
LayoutTests/imported/mozilla/css-animations/test_animation-starttime.html [new file with mode: 0644]
LayoutTests/imported/mozilla/css-animations/test_animations-dynamic-changes-expected.txt [moved from LayoutTests/imported/w3c/web-platform-tests/css/css-animations/Element-getAnimations-dynamic-changes.tentative-expected.txt with 100% similarity]
LayoutTests/imported/mozilla/css-animations/test_animations-dynamic-changes.html [new file with mode: 0644]
LayoutTests/imported/mozilla/css-animations/test_cssanimation-animationname-expected.txt [moved from LayoutTests/imported/w3c/web-platform-tests/css/css-animations/CSSAnimation-animationName.tentative-expected.txt with 100% similarity]
LayoutTests/imported/mozilla/css-animations/test_cssanimation-animationname.html [moved from LayoutTests/imported/w3c/web-platform-tests/css/css-animations/CSSAnimation-animationName.tentative.html with 65% similarity]
LayoutTests/imported/mozilla/css-animations/test_document-get-animations-expected.txt [moved from LayoutTests/imported/w3c/web-platform-tests/css/css-animations/Document-getAnimations.tentative-expected.txt with 59% similarity]
LayoutTests/imported/mozilla/css-animations/test_document-get-animations.html [moved from LayoutTests/imported/w3c/web-platform-tests/css/css-animations/Document-getAnimations.tentative.html with 64% similarity]
LayoutTests/imported/mozilla/css-animations/test_effect-target-expected.txt [moved from LayoutTests/imported/w3c/web-platform-tests/css/css-animations/KeyframeEffect-target.tentative-expected.txt with 100% similarity]
LayoutTests/imported/mozilla/css-animations/test_effect-target.html [moved from LayoutTests/imported/w3c/web-platform-tests/css/css-animations/KeyframeEffect-target.tentative.html with 63% similarity]
LayoutTests/imported/mozilla/css-animations/test_element-get-animations-expected.txt [moved from LayoutTests/imported/w3c/web-platform-tests/css/css-animations/Element-getAnimations.tentative-expected.txt with 57% similarity]
LayoutTests/imported/mozilla/css-animations/test_element-get-animations.html [moved from LayoutTests/imported/w3c/web-platform-tests/css/css-animations/Element-getAnimations.tentative.html with 59% similarity]
LayoutTests/imported/mozilla/css-animations/test_event-dispatch-expected.txt [moved from LayoutTests/imported/w3c/web-platform-tests/css/css-animations/event-dispatch.tentative-expected.txt with 60% similarity]
LayoutTests/imported/mozilla/css-animations/test_event-dispatch.html [new file with mode: 0644]
LayoutTests/imported/mozilla/css-animations/test_event-order-expected.txt [new file with mode: 0644]
LayoutTests/imported/mozilla/css-animations/test_event-order.html [new file with mode: 0644]
LayoutTests/imported/mozilla/css-animations/test_keyframeeffect-getkeyframes-expected.txt [moved from LayoutTests/imported/w3c/web-platform-tests/css/css-animations/KeyframeEffect-getKeyframes.tentative-expected.txt with 99% similarity]
LayoutTests/imported/mozilla/css-animations/test_keyframeeffect-getkeyframes.html [moved from LayoutTests/imported/w3c/web-platform-tests/css/css-animations/KeyframeEffect-getKeyframes.tentative.html with 84% similarity]
LayoutTests/imported/mozilla/css-animations/test_pseudoElement-get-animations-expected.txt [moved from LayoutTests/imported/w3c/web-platform-tests/css/css-animations/CSSPseudoElement-getAnimations.tentative-expected.txt with 60% similarity]
LayoutTests/imported/mozilla/css-animations/test_pseudoElement-get-animations.html [moved from LayoutTests/imported/w3c/web-platform-tests/css/css-animations/CSSPseudoElement-getAnimations.tentative.html with 65% similarity]
LayoutTests/imported/mozilla/css-animations/test_setting-effect-expected.txt [moved from LayoutTests/imported/w3c/web-platform-tests/css/css-animations/CSSAnimation-effect.tentative-expected.txt with 80% similarity]
LayoutTests/imported/mozilla/css-animations/test_setting-effect.html [new file with mode: 0644]
LayoutTests/imported/mozilla/css-transitions/test_animation-cancel-expected.txt [moved from LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/CSSTransition-canceling.tentative-expected.txt with 68% similarity]
LayoutTests/imported/mozilla/css-transitions/test_animation-cancel.html [new file with mode: 0644]
LayoutTests/imported/mozilla/css-transitions/test_animation-computed-timing-expected.txt [moved from LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/AnimationEffect-getComputedTiming.tentative-expected.txt with 79% similarity]
LayoutTests/imported/mozilla/css-transitions/test_animation-computed-timing.html [moved from LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/AnimationEffect-getComputedTiming.tentative.html with 56% similarity]
LayoutTests/imported/mozilla/css-transitions/test_animation-currenttime-expected.txt [new file with mode: 0644]
LayoutTests/imported/mozilla/css-transitions/test_animation-currenttime.html [new file with mode: 0644]
LayoutTests/imported/mozilla/css-transitions/test_animation-finished-expected.txt [new file with mode: 0644]
LayoutTests/imported/mozilla/css-transitions/test_animation-finished.html [new file with mode: 0644]
LayoutTests/imported/mozilla/css-transitions/test_animation-pausing-expected.txt [new file with mode: 0644]
LayoutTests/imported/mozilla/css-transitions/test_animation-pausing.html [new file with mode: 0644]
LayoutTests/imported/mozilla/css-transitions/test_animation-ready-expected.txt [new file with mode: 0644]
LayoutTests/imported/mozilla/css-transitions/test_animation-ready.html [new file with mode: 0644]
LayoutTests/imported/mozilla/css-transitions/test_animation-starttime-expected.txt [new file with mode: 0644]
LayoutTests/imported/mozilla/css-transitions/test_animation-starttime.html [new file with mode: 0644]
LayoutTests/imported/mozilla/css-transitions/test_csstransition-transitionproperty-expected.txt [moved from LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/CSSTransition-transitionProperty.tentative-expected.txt with 100% similarity]
LayoutTests/imported/mozilla/css-transitions/test_csstransition-transitionproperty.html [new file with mode: 0644]
LayoutTests/imported/mozilla/css-transitions/test_document-get-animations-expected.txt [new file with mode: 0644]
LayoutTests/imported/mozilla/css-transitions/test_document-get-animations.html [new file with mode: 0644]
LayoutTests/imported/mozilla/css-transitions/test_effect-target-expected.txt [moved from LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/KeyframeEffect-target.tentative-expected.txt with 100% similarity]
LayoutTests/imported/mozilla/css-transitions/test_effect-target.html [moved from LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/KeyframeEffect-target.tentative.html with 66% similarity]
LayoutTests/imported/mozilla/css-transitions/test_element-get-animations-expected.txt [new file with mode: 0644]
LayoutTests/imported/mozilla/css-transitions/test_element-get-animations.html [new file with mode: 0644]
LayoutTests/imported/mozilla/css-transitions/test_event-dispatch-expected.txt [moved from LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/event-dispatch.tentative-expected.txt with 85% similarity]
LayoutTests/imported/mozilla/css-transitions/test_event-dispatch.html [new file with mode: 0644]
LayoutTests/imported/mozilla/css-transitions/test_keyframeeffect-getkeyframes-expected.txt [new file with mode: 0644]
LayoutTests/imported/mozilla/css-transitions/test_keyframeeffect-getkeyframes.html [new file with mode: 0644]
LayoutTests/imported/mozilla/css-transitions/test_pseudoElement-get-animations-expected.txt [moved from LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/CSSPseudoElement-getAnimations.tentative-expected.txt with 100% similarity]
LayoutTests/imported/mozilla/css-transitions/test_pseudoElement-get-animations.html [moved from LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/CSSPseudoElement-getAnimations.tentative.html with 65% similarity]
LayoutTests/imported/mozilla/css-transitions/test_setting-effect-expected.txt [new file with mode: 0644]
LayoutTests/imported/mozilla/css-transitions/test_setting-effect.html [new file with mode: 0644]
LayoutTests/imported/w3c/ChangeLog
LayoutTests/imported/w3c/resources/import-expectations.json
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/CSSAnimation-canceling.tentative-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/CSSAnimation-canceling.tentative.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/CSSAnimation-effect.tentative.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/CSSAnimation-finished.tentative-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/CSSAnimation-finished.tentative.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/CSSAnimation-getCurrentTime.tentative-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/CSSAnimation-getCurrentTime.tentative.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/CSSAnimation-id.tentative.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/CSSAnimation-pausing.tentative.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/CSSAnimation-playState.tentative.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/CSSAnimation-ready.tentative.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/CSSAnimation-startTime.tentative-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/CSSAnimation-startTime.tentative.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/Element-getAnimations-dynamic-changes.tentative.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/META.yml [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/OWNERS [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/animation-opacity-pause-and-set-time-expected.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/animation-opacity-pause-and-set-time.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/animation-pseudo-dynamic-001-expected.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/animation-pseudo-dynamic-001.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/animation-transform-pause-and-set-time-expected.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/animation-transform-pause-and-set-time.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/animationevent-interface-expected.txt
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/animationevent-interface.js
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/animationevent-marker-pseudoelement-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/animationevent-marker-pseudoelement.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/computed-style-animation-parsing-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/computed-style-animation-parsing.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/event-dispatch.tentative.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/event-order.tentative-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/event-order.tentative.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/historical-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/historical.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/idlharness-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/idlharness.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/inheritance-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/inheritance.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/keyframes-remove-documentElement-crash-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/keyframes-remove-documentElement-crash.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-computed-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-computed.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-delay-computed-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-delay-computed.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-delay-invalid-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-delay-invalid.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-delay-valid-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-delay-valid.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-direction-computed-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-direction-computed.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-direction-invalid-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-direction-invalid.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-direction-valid-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-direction-valid.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-duration-computed-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-duration-computed.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-duration-invalid-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-duration-invalid.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-duration-valid-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-duration-valid.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-fill-mode-computed-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-fill-mode-computed.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-fill-mode-invalid-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-fill-mode-invalid.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-fill-mode-valid-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-fill-mode-valid.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-invalid-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-invalid.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-iteration-count-computed-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-iteration-count-computed.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-iteration-count-invalid-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-iteration-count-invalid.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-iteration-count-valid-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-iteration-count-valid.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-name-computed-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-name-computed.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-name-invalid-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-name-invalid.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-name-valid-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-name-valid.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-play-state-computed-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-play-state-computed.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-play-state-invalid-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-play-state-invalid.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-play-state-valid-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-play-state-valid.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-shorthand-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-shorthand.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-timing-function-computed-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-timing-function-computed.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-timing-function-invalid-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-timing-function-invalid.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-timing-function-valid-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-timing-function-valid.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-valid-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/animation-valid.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/parsing/w3c-import.log [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/responsive/column-rule-color-001-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/responsive/column-rule-color-001.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/responsive/column-width-001-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/responsive/column-width-001.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/responsive/w3c-import.log [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/style-animation-parsing-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/style-animation-parsing.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/support/testcommon.js
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/support/w3c-import.log
LayoutTests/imported/w3c/web-platform-tests/css/css-animations/w3c-import.log
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/CSSTransition-canceling.tentative.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/CSSTransition-currentTime.tentative-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/CSSTransition-currentTime.tentative.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/CSSTransition-effect.tentative-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/CSSTransition-effect.tentative.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/CSSTransition-finished.tentative-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/CSSTransition-finished.tentative.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/CSSTransition-ready.tentative-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/CSSTransition-ready.tentative.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/CSSTransition-startTime.tentative-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/CSSTransition-startTime.tentative.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/CSSTransition-transitionProperty.tentative.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/Document-getAnimations.tentative-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/Document-getAnimations.tentative.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/Element-getAnimations.tentative-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/Element-getAnimations.tentative.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/KeyframeEffect-getKeyframes.tentative-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/KeyframeEffect-getKeyframes.tentative.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/META.yml [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/README.md [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/before-load-001-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/before-load-001.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/changing-while-transition-001-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/changing-while-transition-001.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/changing-while-transition-002-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/changing-while-transition-002.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/changing-while-transition-003-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/changing-while-transition-003.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/currentcolor-animation-001-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/currentcolor-animation-001.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/disconnected-element-001-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/disconnected-element-001.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/event-dispatch.tentative.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/events-001-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/events-001.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/events-002-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/events-002.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/events-003-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/events-003.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/events-004-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/events-004.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/events-005-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/events-005.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/events-006-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/events-006.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/events-007-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/events-007.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/historical-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/historical.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/idlharness-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/idlharness.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/inherit-height-transition-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/inherit-height-transition.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/inheritance-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/inheritance.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/no-transition-from-ua-to-blocking-stylesheet-expected.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/no-transition-from-ua-to-blocking-stylesheet.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/non-rendered-element-001-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/non-rendered-element-001.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/non-rendered-element-002-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/non-rendered-element-002.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/parsing/transition-computed-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/parsing/transition-computed.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/parsing/transition-delay-computed-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/parsing/transition-delay-computed.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/parsing/transition-delay-invalid-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/parsing/transition-delay-invalid.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/parsing/transition-delay-valid-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/parsing/transition-delay-valid.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/parsing/transition-duration-computed-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/parsing/transition-duration-computed.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/parsing/transition-duration-invalid-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/parsing/transition-duration-invalid.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/parsing/transition-duration-valid-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/parsing/transition-duration-valid.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/parsing/transition-invalid-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/parsing/transition-invalid.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/parsing/transition-property-computed-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/parsing/transition-property-computed.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/parsing/transition-property-invalid-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/parsing/transition-property-invalid.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/parsing/transition-property-valid-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/parsing/transition-property-valid.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/parsing/transition-shorthand-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/parsing/transition-shorthand.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/parsing/transition-timing-function-computed-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/parsing/transition-timing-function-computed.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/parsing/transition-timing-function-invalid-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/parsing/transition-timing-function-invalid.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/parsing/transition-timing-function-valid-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/parsing/transition-timing-function-valid.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/parsing/transition-valid-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/parsing/transition-valid.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/parsing/w3c-import.log [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/properties-value-001-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/properties-value-001.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/properties-value-002-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/properties-value-002.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/properties-value-003-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/properties-value-003.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/properties-value-auto-001-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/properties-value-auto-001.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/properties-value-implicit-001-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/properties-value-implicit-001.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/properties-value-inherit-001-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/properties-value-inherit-001.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/properties-value-inherit-002-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/properties-value-inherit-002.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/properties-value-inherit-003-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/properties-value-inherit-003.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/pseudo-elements-001-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/pseudo-elements-001.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/pseudo-elements-002-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/pseudo-elements-002.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/starting-of-transitions-001-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/starting-of-transitions-001.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/1x1-green.png [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/1x1-lime.png [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/1x1-maroon.png [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/1x1-navy.png [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/1x1-red.png [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/1x1-white.png [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/60x60-gg-rr.png [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/60x60-green.png [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/60x60-red.png [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/README [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/a-green-transition.css [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/a-green.css [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/b-green.css [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/c-red.css [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/cat.png [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/generalParallelTest.js [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/helper.js [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/import-green.css [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/import-red.css [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/one.gif [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/pattern-grg-rgr-grg.png [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/pattern-grg-rrg-rgg.png [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/pattern-rgr-grg-rgr.png [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/pattern-tr.png [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/properties.js [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/ruler-h-50%.png [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/ruler-h-50px.png [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/ruler-v-100px.png [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/ruler-v-50px.png [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/runParallelAsyncHarness.js [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/square-purple.png [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/square-teal.png [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/square-white.png [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/support/README [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/support/swatch-green.png [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/support/swatch-red.png [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/support/w3c-import.log [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/swatch-blue.png [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/swatch-green.png [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/swatch-lime.png [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/swatch-orange.png [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/swatch-red.png [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/swatch-teal.png [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/swatch-white.png [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/swatch-yellow.png [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/test-bl.png [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/test-br.png [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/test-inner-half-size.png [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/test-outer.png [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/test-tl.png [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/test-tr.png [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/two.gif [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/vendorPrefix.js [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/support/w3c-import.log [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/transition-001-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/transition-001.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/transition-background-position-with-edge-offset-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/transition-background-position-with-edge-offset.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/transition-delay-001-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/transition-delay-001.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/transition-duration-001-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/transition-duration-001.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/transition-property-001-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/transition-property-001.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/transition-property-002-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/transition-property-002.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/transition-reparented-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/transition-reparented.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/transition-test-expected.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/transition-test.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/transitioncancel-001-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/transitioncancel-001.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/transitionevent-interface-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/transitionevent-interface.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/w3c-import.log [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/zero-duration-multiple-transition-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/css/css-transitions/zero-duration-multiple-transition.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/web-animations/animation-model/animation-types/accumulation-per-property-expected.txt
LayoutTests/imported/w3c/web-platform-tests/web-animations/animation-model/animation-types/addition-per-property-expected.txt
LayoutTests/imported/w3c/web-platform-tests/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt
LayoutTests/imported/w3c/web-platform-tests/web-animations/animation-model/animation-types/property-types.js
LayoutTests/imported/w3c/web-platform-tests/web-animations/animation-model/animation-types/w3c-import.log [deleted file]
LayoutTests/imported/w3c/web-platform-tests/web-animations/animation-model/combining-effects/w3c-import.log [deleted file]
LayoutTests/imported/w3c/web-platform-tests/web-animations/animation-model/keyframe-effects/w3c-import.log [deleted file]
LayoutTests/imported/w3c/web-platform-tests/web-animations/interfaces/Animatable/w3c-import.log [deleted file]
LayoutTests/imported/w3c/web-platform-tests/web-animations/interfaces/Animation/idlharness.window-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/web-animations/interfaces/Animation/idlharness.window.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/web-animations/interfaces/Animation/oncancel.html
LayoutTests/imported/w3c/web-platform-tests/web-animations/interfaces/Animation/w3c-import.log [deleted file]
LayoutTests/imported/w3c/web-platform-tests/web-animations/interfaces/AnimationEffect/w3c-import.log [deleted file]
LayoutTests/imported/w3c/web-platform-tests/web-animations/interfaces/AnimationPlaybackEvent/idlharness.window-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/web-animations/interfaces/AnimationPlaybackEvent/idlharness.window.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/web-animations/interfaces/AnimationPlaybackEvent/w3c-import.log [deleted file]
LayoutTests/imported/w3c/web-platform-tests/web-animations/interfaces/Document/getAnimations-expected.txt
LayoutTests/imported/w3c/web-platform-tests/web-animations/interfaces/Document/getAnimations.html
LayoutTests/imported/w3c/web-platform-tests/web-animations/interfaces/Document/w3c-import.log [deleted file]
LayoutTests/imported/w3c/web-platform-tests/web-animations/interfaces/DocumentTimeline/idlharness.window-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/web-animations/interfaces/DocumentTimeline/idlharness.window.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/web-animations/interfaces/DocumentTimeline/w3c-import.log [deleted file]
LayoutTests/imported/w3c/web-platform-tests/web-animations/interfaces/KeyframeEffect/idlharness.window-expected.txt [deleted file]
LayoutTests/imported/w3c/web-platform-tests/web-animations/interfaces/KeyframeEffect/idlharness.window.html [deleted file]
LayoutTests/imported/w3c/web-platform-tests/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-001-expected.txt
LayoutTests/imported/w3c/web-platform-tests/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-001.html
LayoutTests/imported/w3c/web-platform-tests/web-animations/interfaces/KeyframeEffect/w3c-import.log [deleted file]
LayoutTests/imported/w3c/web-platform-tests/web-animations/resources/w3c-import.log [deleted file]
LayoutTests/imported/w3c/web-platform-tests/web-animations/timing-model/animation-effects/w3c-import.log [deleted file]
LayoutTests/imported/w3c/web-platform-tests/web-animations/timing-model/animations/w3c-import.log [deleted file]
LayoutTests/imported/w3c/web-platform-tests/web-animations/timing-model/time-transformations/w3c-import.log [deleted file]
LayoutTests/imported/w3c/web-platform-tests/web-animations/timing-model/timelines/w3c-import.log [deleted file]
LayoutTests/imported/w3c/web-platform-tests/web-animations/w3c-import.log [deleted file]
LayoutTests/platform/gtk/TestExpectations
LayoutTests/platform/gtk/imported/w3c/web-platform-tests/web-animations/animation-model/animation-types/accumulation-per-property-expected.txt
LayoutTests/platform/gtk/imported/w3c/web-platform-tests/web-animations/animation-model/animation-types/addition-per-property-expected.txt
LayoutTests/platform/ios/imported/w3c/web-platform-tests/web-animations/animation-model/animation-types/accumulation-per-property-expected.txt
LayoutTests/platform/ios/imported/w3c/web-platform-tests/web-animations/animation-model/animation-types/addition-per-property-expected.txt
LayoutTests/platform/ios/imported/w3c/web-platform-tests/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt
LayoutTests/platform/mac-sierra/imported/w3c/web-platform-tests/web-animations/animation-model/animation-types/accumulation-per-property-expected.txt
LayoutTests/platform/mac-sierra/imported/w3c/web-platform-tests/web-animations/animation-model/animation-types/addition-per-property-expected.txt
LayoutTests/platform/mac-wk1/TestExpectations
LayoutTests/platform/win/TestExpectations
LayoutTests/platform/wpe/imported/w3c/web-platform-tests/web-animations/animation-model/animation-types/accumulation-per-property-expected.txt
LayoutTests/platform/wpe/imported/w3c/web-platform-tests/web-animations/animation-model/animation-types/addition-per-property-expected.txt
LayoutTests/tests-options.json

index a55da76..3855a79 100644 (file)
@@ -1,3 +1,16 @@
+2019-10-24  Russell Epstein  <repstein@apple.com>
+
+        Unreviewed, rolling out r251536.
+
+        Landed 3 Broken Tests.
+
+        Reverted changeset:
+
+        "[Web Animations] Update WPT tests related to Web Animations
+        and remove imported Mozilla tests"
+        https://bugs.webkit.org/show_bug.cgi?id=203291
+        https://trac.webkit.org/changeset/251536
+
 2019-10-24  Commit Queue  <commit-queue@webkit.org>
 
         Unreviewed, rolling out r251269, r251294, and r251328.
index ffc3ae7..29132ce 100644 (file)
@@ -2802,6 +2802,13 @@ webkit.org/b/202107 imported/w3c/web-platform-tests/web-animations/interfaces/An
 webkit.org/b/202108 imported/w3c/web-platform-tests/web-animations/interfaces/DocumentTimeline/style-change-events.html [ Pass Failure ]
 webkit.org/b/202109 imported/w3c/web-platform-tests/web-animations/timing-model/timelines/update-and-send-events.html [ Pass Failure ]
 
+webkit.org/b/183836 imported/mozilla/css-animations/test_animations-dynamic-changes.html [ Pass Failure Timeout ]
+webkit.org/b/183844 imported/mozilla/css-animations/test_element-get-animations.html [ Pass Failure Timeout ]
+webkit.org/b/183846 imported/mozilla/css-transitions/test_pseudoElement-get-animations.html [ Pass Failure Timeout ]
+webkit.org/b/183847 imported/mozilla/css-animations/test_event-order.html [ Pass Failure Timeout ]
+
+webkit.org/b/183848 imported/mozilla/css-animations/test_keyframeeffect-getkeyframes.html [ Skip ]
+
 webkit.org/b/157068 [ Debug ] imported/w3c/web-platform-tests/fetch/nosniff/importscripts.html [ Pass Crash ]
 webkit.org/b/157068 [ Release ] imported/w3c/web-platform-tests/fetch/nosniff/importscripts.html [ Pass Failure ]
 
@@ -3878,8 +3885,6 @@ webkit.org/b/200207 imported/w3c/web-platform-tests/css/css-images/css-image-fal
 webkit.org/b/200208 imported/w3c/web-platform-tests/css/css-images/gradients-with-transparent.html [ ImageOnlyFailure ]
 webkit.org/b/200209 imported/w3c/web-platform-tests/css/css-images/multiple-position-color-stop-radial.html [ ImageOnlyFailure ]
 
-webkit.org/b/203296 imported/w3c/web-platform-tests/css/css-animations/keyframes-remove-documentElement-crash.html [ Skip ]
-
 # wpt css-values failures
 webkit.org/b/203320 imported/w3c/web-platform-tests/css/css-values/percentage-rem-low.html [ ImageOnlyFailure ]
 webkit.org/b/203321 imported/w3c/web-platform-tests/css/css-values/q-unit-case-insensitivity-001.html [ ImageOnlyFailure ]
index 708c2b6..9ece31e 100644 (file)
@@ -1,3 +1,16 @@
+2019-10-24  Russell Epstein  <repstein@apple.com>
+
+        Unreviewed, rolling out r251536.
+
+        Landed 3 Broken Tests.
+
+        Reverted changeset:
+
+        "[Web Animations] Update WPT tests related to Web Animations
+        and remove imported Mozilla tests"
+        https://bugs.webkit.org/show_bug.cgi?id=203291
+        https://trac.webkit.org/changeset/251536
+
 2019-10-24  Antoine Quint  <graouts@apple.com>
 
         [Web Animations] Update WPT tests related to Web Animations and remove imported Mozilla tests
diff --git a/LayoutTests/imported/mozilla/css-animations/test_animation-cancel-expected.txt b/LayoutTests/imported/mozilla/css-animations/test_animation-cancel-expected.txt
new file mode 100644 (file)
index 0000000..d68b752
--- /dev/null
@@ -0,0 +1,11 @@
+
+PASS Animated style is cleared after cancelling a running CSS animation 
+PASS Animated style is cleared after cancelling a filling CSS animation 
+PASS After canceling an animation, it can still be seeked 
+PASS After cancelling an animation, it can still be re-used 
+PASS After cancelling an animation, updating animation properties doesn't make it live again 
+PASS After cancelling an animation, updating animation-play-state doesn't make it live again 
+PASS Setting animation-name to 'none' cancels the animation 
+PASS Setting display:none on an element cancel its animations 
+PASS Setting display:none on an ancestor element cancels animations on descendants 
+
diff --git a/LayoutTests/imported/mozilla/css-animations/test_animation-cancel.html b/LayoutTests/imported/mozilla/css-animations/test_animation-cancel.html
new file mode 100644 (file)
index 0000000..fa877a2
--- /dev/null
@@ -0,0 +1,193 @@
+<!doctype html>
+<meta charset=utf-8>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="../resources/testcommon.js"></script>
+<style>
+@keyframes translateAnim {
+  to { transform: translate(100px) }
+}
+@keyframes marginLeftAnim {
+  to { margin-left: 100px }
+}
+@keyframes marginLeftAnim100To200 {
+  from { margin-left: 100px }
+  to { margin-left: 200px }
+}
+</style>
+<body>
+<div id="log"></div>
+<script>
+'use strict';
+
+promise_test(function(t) {
+  var div = addDiv(t, { style: 'animation: translateAnim 100s' });
+  var animation = div.getAnimations()[0];
+
+  return animation.ready.then(function() {
+    assert_not_equals(getComputedStyle(div).transform, 'none',
+                      'transform style is animated before cancelling');
+    animation.cancel();
+    assert_equals(getComputedStyle(div).transform, 'none',
+                  'transform style is no longer animated after cancelling');
+  });
+}, 'Animated style is cleared after cancelling a running CSS animation');
+
+promise_test(function(t) {
+  var div = addDiv(t, { style: 'animation: translateAnim 100s forwards' });
+  var animation = div.getAnimations()[0];
+  animation.finish();
+
+  return animation.ready.then(function() {
+    assert_not_equals(getComputedStyle(div).transform, 'none',
+                      'transform style is filling before cancelling');
+    animation.cancel();
+    assert_equals(getComputedStyle(div).transform, 'none',
+                  'fill style is cleared after cancelling');
+  });
+}, 'Animated style is cleared after cancelling a filling CSS animation');
+
+test(function(t) {
+  var div = addDiv(t, { style: 'animation: marginLeftAnim 100s linear' });
+  var animation = div.getAnimations()[0];
+  animation.cancel();
+
+  assert_equals(getComputedStyle(div).marginLeft, '0px',
+                'margin-left style is not animated after cancelling');
+
+  animation.currentTime = 50 * 1000;
+  assert_equals(getComputedStyle(div).marginLeft, '50px',
+                'margin-left style is updated when cancelled animation is'
+                + ' seeked');
+}, 'After canceling an animation, it can still be seeked');
+
+promise_test(function(t) {
+  var div =
+    addDiv(t, { style: 'animation: marginLeftAnim100To200 100s linear' });
+  var animation = div.getAnimations()[0];
+
+  return animation.ready.then(function() {
+    animation.cancel();
+    assert_equals(getComputedStyle(div).marginLeft, '0px',
+                  'margin-left style is not animated after cancelling');
+    animation.play();
+    assert_equals(getComputedStyle(div).marginLeft, '100px',
+                  'margin-left style is animated after re-starting animation');
+    return animation.ready;
+  }).then(function() {
+    assert_equals(animation.playState, 'running',
+                  'Animation succeeds in running after being re-started');
+  });
+}, 'After cancelling an animation, it can still be re-used');
+
+test(function(t) {
+  var div =
+    addDiv(t, { style: 'animation: marginLeftAnim100To200 100s linear' });
+  var animation = div.getAnimations()[0];
+  animation.cancel();
+  assert_equals(getComputedStyle(div).marginLeft, '0px',
+                'margin-left style is not animated after cancelling');
+
+  // Trigger a change to some animation properties and check that this
+  // doesn't cause the animation to become live again
+  div.style.animationDuration = '200s';
+  assert_equals(getComputedStyle(div).marginLeft, '0px',
+                'margin-left style is still not animated after updating'
+                + ' animation-duration');
+  assert_equals(animation.playState, 'idle',
+                'Animation is still idle after updating animation-duration');
+}, 'After cancelling an animation, updating animation properties doesn\'t make'
+   + ' it live again');
+
+test(function(t) {
+  var div =
+    addDiv(t, { style: 'animation: marginLeftAnim100To200 100s linear' });
+  var animation = div.getAnimations()[0];
+  animation.cancel();
+  assert_equals(getComputedStyle(div).marginLeft, '0px',
+                'margin-left style is not animated after cancelling');
+
+  // Make some changes to animation-play-state and check that the
+  // animation doesn't become live again. This is because it should be
+  // possible to cancel an animation from script such that all future
+  // changes to style are ignored.
+
+  // Redundant change
+  div.style.animationPlayState = 'running';
+  assert_equals(animation.playState, 'idle',
+                'Animation is still idle after a redundant change to'
+                + ' animation-play-state');
+
+  // Pause
+  div.style.animationPlayState = 'paused';
+  assert_equals(animation.playState, 'idle',
+                'Animation is still idle after setting'
+                + ' animation-play-state: paused');
+
+  // Play
+  div.style.animationPlayState = 'running';
+  assert_equals(animation.playState, 'idle',
+                'Animation is still idle after re-setting'
+                + ' animation-play-state: running');
+
+}, 'After cancelling an animation, updating animation-play-state doesn\'t'
+   + ' make it live again');
+
+promise_test(function(t) {
+  var div = addDiv(t, { style: 'animation: translateAnim 10s both' });
+  div.style.marginLeft = '0px';
+
+  var animation = div.getAnimations()[0];
+
+  return animation.ready.then(function() {
+    assert_equals(animation.playState, 'running');
+
+    div.style.animationName = 'none';
+    flushComputedStyle(div);
+    return waitForFrame();
+  }).then(function() {
+    assert_equals(animation.playState, 'idle');
+    assert_equals(getComputedStyle(div).marginLeft, '0px');
+  });
+}, 'Setting animation-name to \'none\' cancels the animation');
+
+promise_test(function(t) {
+  var div = addDiv(t, { style: 'animation: translateAnim 10s both' });
+  var animation = div.getAnimations()[0];
+
+  return animation.ready.then(function() {
+    assert_equals(animation.playState, 'running');
+
+    div.style.display = 'none';
+    return waitForFrame();
+  }).then(function() {
+    assert_equals(animation.playState, 'idle');
+    assert_equals(getComputedStyle(div).marginLeft, '0px');
+  });
+}, 'Setting display:none on an element cancel its animations');
+
+promise_test(function(t) {
+  var parentDiv = addDiv(t);
+  var childDiv  = document.createElement('div');
+  parentDiv.appendChild(childDiv);
+
+  childDiv.setAttribute('style', 'animation: translateAnim 10s both');
+  flushComputedStyle(childDiv);
+
+  var animation = childDiv.getAnimations()[0];
+
+  return animation.ready.then(function() {
+    assert_equals(animation.playState, 'running');
+
+    parentDiv.style.display = 'none';
+    return waitForFrame();
+  }).then(function() {
+    assert_equals(animation.playState, 'idle');
+    assert_equals(getComputedStyle(childDiv).marginLeft, '0px');
+  });
+}, 'Setting display:none on an ancestor element cancels animations on ' +
+   'descendants');
+
+</script>
+</body>
+</html>
@@ -1,11 +1,8 @@
 <!doctype html>
 <meta charset=utf-8>
-<title>AnimationEffect.getComputedTiming() for CSS animations</title>
-<!--  TODO: Add a more specific link for this once it is specified.  -->
-<link rel="help" href="https://drafts.csswg.org/css-animations-2/#cssanimation">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="support/testcommon.js"></script>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="../resources/testcommon.js"></script>
 <style>
 @keyframes moveAnimation {
   from { margin-left: 100px }
 // --------------------
 // delay
 // --------------------
-
-test(t => {
-  const div = addDiv(t, { style: 'animation: moveAnimation 100s' });
-  const effect = div.getAnimations()[0].effect;
-  assert_equals(effect.getComputedTiming().delay, 0, 'Initial value of delay');
+test(function(t) {
+  var div = addDiv(t, {style: 'animation: moveAnimation 100s'});
+  var effect = div.getAnimations()[0].effect;
+  assert_equals(effect.getComputedTiming().delay, 0,
+                'Initial value of delay');
 }, 'delay of a new animation');
 
-test(t => {
-  const div = addDiv(t, { style: 'animation: moveAnimation 100s -10s' });
-  const effect = div.getAnimations()[0].effect;
+test(function(t) {
+  var div = addDiv(t, {style: 'animation: moveAnimation 100s -10s'});
+  var effect = div.getAnimations()[0].effect;
   assert_equals(effect.getComputedTiming().delay, -10 * MS_PER_SEC,
                 'Initial value of delay');
 }, 'Negative delay of a new animation');
 
-test(t => {
-  const div = addDiv(t, { style: 'animation: moveAnimation 100s 10s' });
-  const effect = div.getAnimations()[0].effect;
+test(function(t) {
+  var div = addDiv(t, {style: 'animation: moveAnimation 100s 10s'});
+  var effect = div.getAnimations()[0].effect;
   assert_equals(effect.getComputedTiming().delay, 10 * MS_PER_SEC,
                 'Initial value of delay');
 }, 'Positive delay of a new animation');
@@ -46,10 +43,9 @@ test(t => {
 // --------------------
 // endDelay
 // --------------------
-
-test(t => {
-  const div = addDiv(t, { style: 'animation: moveAnimation 100s' });
-  const effect = div.getAnimations()[0].effect;
+test(function(t) {
+  var div = addDiv(t, {style: 'animation: moveAnimation 100s'});
+  var effect = div.getAnimations()[0].effect;
   assert_equals(effect.getComputedTiming().endDelay, 0,
                 'Initial value of endDelay');
 }, 'endDelay of a new animation');
@@ -58,14 +54,13 @@ test(t => {
 // --------------------
 // fill
 // --------------------
-
-test(t => {
-  const getEffectWithFill = fill => {
-    const div = addDiv(t, { style: 'animation: moveAnimation 100s ' + fill });
+test(function(t) {
+  var getEffectWithFill = function(fill) {
+    var div = addDiv(t, {style: 'animation: moveAnimation 100s ' + fill});
     return div.getAnimations()[0].effect;
   };
 
-  let effect = getEffectWithFill('');
+  var effect = getEffectWithFill('');
   assert_equals(effect.getComputedTiming().fill, 'none',
                 'Initial value of fill');
   effect = getEffectWithFill('forwards');
@@ -83,10 +78,9 @@ test(t => {
 // --------------------
 // iterationStart
 // --------------------
-
-test(t => {
-  const div = addDiv(t, { style: 'animation: moveAnimation 100s' });
-  const effect = div.getAnimations()[0].effect;
+test(function(t) {
+  var div = addDiv(t, {style: 'animation: moveAnimation 100s'});
+  var effect = div.getAnimations()[0].effect;
   assert_equals(effect.getComputedTiming().iterationStart, 0,
                 'Initial value of iterationStart');
 }, 'iterationStart of a new animation');
@@ -95,24 +89,23 @@ test(t => {
 // --------------------
 // iterations
 // --------------------
-
-test(t => {
-  const div = addDiv(t, { style: 'animation: moveAnimation 100s' });
-  const effect = div.getAnimations()[0].effect;
+test(function(t) {
+  var div = addDiv(t, {style: 'animation: moveAnimation 100s'});
+  var effect = div.getAnimations()[0].effect;
   assert_equals(effect.getComputedTiming().iterations, 1,
                 'Initial value of iterations');
 }, 'iterations of a new animation');
 
-test(t => {
-  const div = addDiv(t, { style: 'animation: moveAnimation 100s 2016.5' });
-  const effect = div.getAnimations()[0].effect;
+test(function(t) {
+  var div = addDiv(t, {style: 'animation: moveAnimation 100s 2016.5'});
+  var effect = div.getAnimations()[0].effect;
   assert_equals(effect.getComputedTiming().iterations, 2016.5,
                 'Initial value of iterations');
 }, 'iterations of a finitely repeating animation');
 
-test(t => {
-  const div = addDiv(t, { style: 'animation: moveAnimation 100s infinite' });
-  const effect = div.getAnimations()[0].effect;
+test(function(t) {
+  var div = addDiv(t, {style: 'animation: moveAnimation 100s infinite'});
+  var effect = div.getAnimations()[0].effect;
   assert_equals(effect.getComputedTiming().iterations, Infinity,
                 'Initial value of iterations');
 }, 'iterations of an infinitely repeating animation');
@@ -121,12 +114,9 @@ test(t => {
 // --------------------
 // duration
 // --------------------
-
-test(t => {
-  const div = addDiv(t, {
-    style: 'animation: moveAnimation 100s -10s infinite'
-  });
-  const effect = div.getAnimations()[0].effect;
+test(function(t) {
+  var div = addDiv(t, {style: 'animation: moveAnimation 100s -10s infinite'});
+  var effect = div.getAnimations()[0].effect;
   assert_equals(effect.getComputedTiming().duration, 100 * MS_PER_SEC,
                 'Initial value of duration');
 }, 'duration of a new animation');
@@ -135,14 +125,13 @@ test(t => {
 // --------------------
 // direction
 // --------------------
-
-test(t => {
-  const getEffectWithDir = dir => {
-    const div = addDiv(t, { style: 'animation: moveAnimation 100s ' + dir });
+test(function(t) {
+  var getEffectWithDir = function(dir) {
+    var div = addDiv(t, {style: 'animation: moveAnimation 100s ' + dir});
     return div.getAnimations()[0].effect;
   };
 
-  let effect = getEffectWithDir('');
+  var effect = getEffectWithDir('');
   assert_equals(effect.getComputedTiming().direction, 'normal',
                 'Initial value of normal direction');
   effect = getEffectWithDir('reverse');
@@ -160,10 +149,9 @@ test(t => {
 // --------------------
 // easing
 // --------------------
-
-test(t => {
-  const div = addDiv(t, { style: 'animation: moveAnimation 100s' });
-  const effect = div.getAnimations()[0].effect;
+test(function(t) {
+  var div = addDiv(t, {style: 'animation: moveAnimation 100s'});
+  var effect = div.getAnimations()[0].effect;
   assert_equals(effect.getComputedTiming().easing, 'linear',
                 'Initial value of easing');
 }, 'easing of a new animation');
@@ -173,45 +161,40 @@ test(t => {
 // endTime
 // = max(start delay + active duration + end delay, 0)
 // --------------------
-
-test(t => {
-  const div = addDiv(t, { style: 'animation: moveAnimation 100s' });
-  const effect = div.getAnimations()[0].effect;
+test(function(t) {
+  var div = addDiv(t, {style: 'animation: moveAnimation 100s'});
+  var effect = div.getAnimations()[0].effect;
   assert_equals(effect.getComputedTiming().endTime, 100 * MS_PER_SEC,
                 'Initial value of endTime');
 }, 'endTime of an new animation');
 
-test(t => {
-  const div = addDiv(t, { style: 'animation: moveAnimation 100s -5s' });
-  const effect = div.getAnimations()[0].effect;
-  const answer = (100 - 5) * MS_PER_SEC;
+test(function(t) {
+  var div = addDiv(t, {style: 'animation: moveAnimation 100s -5s'});
+  var effect = div.getAnimations()[0].effect;
+  var answer = (100 - 5) * MS_PER_SEC;
   assert_equals(effect.getComputedTiming().endTime, answer,
                 'Initial value of endTime');
 }, 'endTime of an animation with a negative delay');
 
-test(t => {
-  const div = addDiv(t, {
-    style: 'animation: moveAnimation 10s -100s infinite'
-  });
-  const effect = div.getAnimations()[0].effect;
+test(function(t) {
+  var div = addDiv(t, {style: 'animation: moveAnimation 10s -100s infinite'});
+  var effect = div.getAnimations()[0].effect;
   assert_equals(effect.getComputedTiming().endTime, Infinity,
                 'Initial value of endTime');
 }, 'endTime of an infinitely repeating animation');
 
-test(t => {
-  const div = addDiv(t, { style: 'animation: moveAnimation 0s 100s infinite' });
-  const effect = div.getAnimations()[0].effect;
+test(function(t) {
+  var div = addDiv(t, {style: 'animation: moveAnimation 0s 100s infinite'});
+  var effect = div.getAnimations()[0].effect;
   assert_equals(effect.getComputedTiming().endTime, 100 * MS_PER_SEC,
                 'Initial value of endTime');
 }, 'endTime of an infinitely repeating zero-duration animation');
 
-test(t => {
+test(function(t) {
   // Fill forwards so div.getAnimations()[0] won't return an
   // undefined value.
-  const div = addDiv(t, {
-    style: 'animation: moveAnimation 10s -100s forwards'
-  });
-  const effect = div.getAnimations()[0].effect;
+  var div = addDiv(t, {style: 'animation: moveAnimation 10s -100s forwards'});
+  var effect = div.getAnimations()[0].effect;
   assert_equals(effect.getComputedTiming().endTime, 0,
                 'Initial value of endTime');
 }, 'endTime of an animation that finishes before its startTime');
@@ -221,34 +204,33 @@ test(t => {
 // activeDuration
 // = iteration duration * iteration count
 // --------------------
-
-test(t => {
-  const div = addDiv(t, { style: 'animation: moveAnimation 100s 5' });
-  const effect = div.getAnimations()[0].effect;
-  const answer = 100 * MS_PER_SEC * 5;
+test(function(t) {
+  var div = addDiv(t, {style: 'animation: moveAnimation 100s 5'});
+  var effect = div.getAnimations()[0].effect;
+  var answer = 100 * MS_PER_SEC * 5;
   assert_equals(effect.getComputedTiming().activeDuration, answer,
                 'Initial value of activeDuration');
 }, 'activeDuration of a new animation');
 
-test(t => {
-  const div = addDiv(t, { style: 'animation: moveAnimation 100s infinite' });
-  const effect = div.getAnimations()[0].effect;
+test(function(t) {
+  var div = addDiv(t, {style: 'animation: moveAnimation 100s infinite'});
+  var effect = div.getAnimations()[0].effect;
   assert_equals(effect.getComputedTiming().activeDuration, Infinity,
                 'Initial value of activeDuration');
 }, 'activeDuration of an infinitely repeating animation');
 
-test(t => {
-  const div = addDiv(t, { style: 'animation: moveAnimation 0s 1s infinite' });
-  const effect = div.getAnimations()[0].effect;
+test(function(t) {
+  var div = addDiv(t, {style: 'animation: moveAnimation 0s 1s infinite'});
+  var effect = div.getAnimations()[0].effect;
   // If either the iteration duration or iteration count are zero,
   // the active duration is zero.
   assert_equals(effect.getComputedTiming().activeDuration, 0,
                 'Initial value of activeDuration');
 }, 'activeDuration of an infinitely repeating zero-duration animation');
 
-test(t => {
-  const div = addDiv(t, { style: 'animation: moveAnimation 100s 1s 0' });
-  const effect = div.getAnimations()[0].effect;
+test(function(t) {
+  var div = addDiv(t, {style: 'animation: moveAnimation 100s 1s 0'});
+  var effect = div.getAnimations()[0].effect;
   // If either the iteration duration or iteration count are zero,
   // the active duration is zero.
   assert_equals(effect.getComputedTiming().activeDuration, 0,
@@ -259,42 +241,40 @@ test(t => {
 // --------------------
 // localTime
 // --------------------
-
-test(t => {
-  const div = addDiv(t, { style: 'animation: moveAnimation 100s' });
-  const effect = div.getAnimations()[0].effect;
+test(function(t) {
+  var div = addDiv(t, {style: 'animation: moveAnimation 100s'});
+  var effect = div.getAnimations()[0].effect;
   assert_equals(effect.getComputedTiming().localTime, 0,
                 'Initial value of localTime');
 }, 'localTime of a new animation');
 
-test(t => {
-  const div = addDiv(t, { style: 'animation: moveAnimation 100s' });
-  const anim = div.getAnimations()[0];
+test(function(t) {
+  var div = addDiv(t, {style: 'animation: moveAnimation 100s'});
+  var anim = div.getAnimations()[0];
   anim.currentTime = 5 * MS_PER_SEC;
   assert_equals(anim.effect.getComputedTiming().localTime, anim.currentTime,
                 'current localTime after setting currentTime');
 }, 'localTime of an animation is always equal to currentTime');
 
-promise_test(async t => {
-  const div = addDiv(t, { style: 'animation: moveAnimation 100s' });
+promise_test(function(t) {
+  var div = addDiv(t, {style: 'animation: moveAnimation 100s'});
 
-  const anim = div.getAnimations()[0];
+  var anim = div.getAnimations()[0];
   anim.playbackRate = 2; // 2 times faster
 
-  await anim.ready;
-
-  assert_equals(anim.effect.getComputedTiming().localTime, anim.currentTime,
-                'localTime is equal to currentTime');
-
-  await waitForFrame();
-
-  assert_equals(anim.effect.getComputedTiming().localTime, anim.currentTime,
-                'localTime is equal to currentTime');
+  return anim.ready.then(function() {
+    assert_equals(anim.effect.getComputedTiming().localTime, anim.currentTime,
+                  'localTime is equal to currentTime');
+    return waitForFrame();
+  }).then(function() {
+    assert_equals(anim.effect.getComputedTiming().localTime, anim.currentTime,
+                  'localTime is equal to currentTime');
+  });
 }, 'localTime reflects playbackRate immediately');
 
-test(t => {
-  const div = addDiv(t);
-  const effect = new KeyframeEffect(div, {left: ["0px", "100px"]});
+test(function(t) {
+  var div = addDiv(t);
+  var effect = new KeyframeEffect(div, {left: ["0px", "100px"]});
 
   assert_equals(effect.getComputedTiming().localTime, null,
                 'localTime for orphaned effect');
@@ -303,38 +283,29 @@ test(t => {
 
 // --------------------
 // progress
-//
-// Note: Even though CSS animations have a default animation-timing-function of
-// "ease", this only applies between keyframes (often referred to as the
-// keyframe-level easing). The progress value returned by getComputedTiming(),
-// however, only reflects effect-level easing and this defaults to "linear",
-// even for CSS animations.
+// Note: Default timing function is linear.
 // --------------------
-
-test(t => {
-  const tests = [
-    { fill: '', progress: [null, null] },
-    { fill: 'none', progress: [null, null] },
-    { fill: 'forwards', progress: [null, 1.0] },
-    { fill: 'backwards', progress: [0.0, null] },
-    { fill: 'both', progress: [0.0, 1.0] },
-  ];
-  for (const test of tests) {
-    const div = addDiv(t, {
-      style: 'animation: moveAnimation 100s 10s ' + test.fill
-    });
-    const anim = div.getAnimations()[0];
+test(function(t) {
+  [{fill: '',          progress: [ null, null ]},
+   {fill: 'none',      progress: [ null, null ]},
+   {fill: 'forwards',  progress: [ null, 1.0 ]},
+   {fill: 'backwards', progress: [ 0.0, null ]},
+   {fill: 'both',      progress: [ 0.0, 1.0 ]}]
+  .forEach(function(test) {
+    var div =
+      addDiv(t, {style: 'animation: moveAnimation 100s 10s ' + test.fill});
+    var anim = div.getAnimations()[0];
     assert_true(anim.effect.getComputedTiming().progress === test.progress[0],
-                `Initial progress with "${test.fill}" fill`);
+                'initial progress with "' + test.fill + '" fill');
     anim.finish();
     assert_true(anim.effect.getComputedTiming().progress === test.progress[1],
-                `Initial progress with "${test.fill}" fill`);
-  }
+                'finished progress with "' + test.fill + '" fill');
+  });
 }, 'progress of an animation with different fill modes');
 
-test(t => {
-  const div = addDiv(t, { style: 'animation: moveAnimation 10s 10 both' });
-  const anim = div.getAnimations()[0];
+test(function(t) {
+  var div = addDiv(t, {style: 'animation: moveAnimation 10s 10 both'});
+  var anim = div.getAnimations()[0];
 
   assert_equals(anim.effect.getComputedTiming().progress, 0.0,
                 'Initial value of progress');
@@ -352,14 +323,15 @@ test(t => {
                 'Value of progress');
 }, 'progress of an integral repeating animation with normal direction');
 
-test(t => {
+test(function(t) {
+  var div = addDiv(t);
   // Note: FillMode here is "both" because
   // 1. Since this a zero-duration animation, it will already have finished
   //    so it won't be returned by getAnimations() unless it fills forwards.
   // 2. Fill backwards, so the progress before phase wouldn't be
   //    unresolved (null value).
-  const div = addDiv(t, { style: 'animation: moveAnimation 0s infinite both' });
-  const anim = div.getAnimations()[0];
+  var div = addDiv(t, {style: 'animation: moveAnimation 0s infinite both'});
+  var anim = div.getAnimations()[0];
 
   assert_equals(anim.effect.getComputedTiming().progress, 1.0,
                 'Initial value of progress in after phase');
@@ -370,10 +342,10 @@ test(t => {
                 'Value of progress before phase');
 }, 'progress of an infinitely repeating zero-duration animation');
 
-test(t => {
+test(function(t) {
   // Default iterations = 1
-  const div = addDiv(t, { style: 'animation: moveAnimation 0s both' });
-  const anim = div.getAnimations()[0];
+  var div = addDiv(t, {style: 'animation: moveAnimation 0s both'});
+  var anim = div.getAnimations()[0];
 
   assert_equals(anim.effect.getComputedTiming().progress, 1.0,
                 'Initial value of progress in after phase');
@@ -384,9 +356,9 @@ test(t => {
                 'Value of progress before phase');
 }, 'progress of a finitely repeating zero-duration animation');
 
-test(t => {
-  const div = addDiv(t, { style: 'animation: moveAnimation 0s 5s 10.25 both' });
-  const anim = div.getAnimations()[0];
+test(function(t) {
+  var div = addDiv(t, {style: 'animation: moveAnimation 0s 5s 10.25 both'});
+  var anim = div.getAnimations()[0];
 
   assert_equals(anim.effect.getComputedTiming().progress, 0.0,
                 'Initial value of progress (before phase)');
@@ -398,11 +370,9 @@ test(t => {
                 'Value of progress in after phase');
 }, 'progress of a non-integral repeating zero-duration animation');
 
-test(t => {
-  const div = addDiv(t, {
-    style: 'animation: moveAnimation 0s 5s 10.25 both reverse',
-  });
-  const anim = div.getAnimations()[0];
+test(function(t) {
+  var div = addDiv(t, {style: 'animation: moveAnimation 0s 5s 10.25 both reverse'});
+  var anim = div.getAnimations()[0];
 
   assert_equals(anim.effect.getComputedTiming().progress, 1.0,
                 'Initial value of progress (before phase)');
@@ -414,11 +384,9 @@ test(t => {
 }, 'Progress of a non-integral repeating zero-duration animation ' +
    'with reversing direction');
 
-test(t => {
-  const div = addDiv(t, {
-    style: 'animation: moveAnimation 10s 10.25 both alternate',
-  });
-  const anim = div.getAnimations()[0];
+test(function(t) {
+  var div = addDiv(t, {style: 'animation: moveAnimation 10s 10.25 both alternate'});
+  var anim = div.getAnimations()[0];
 
   assert_equals(anim.effect.getComputedTiming().progress, 0.0,
                 'Initial value of progress');
@@ -437,11 +405,9 @@ test(t => {
 }, 'progress of a non-integral repeating animation ' +
    'with alternate direction');
 
-test(t => {
-  const div = addDiv(t, {
-    style: 'animation: moveAnimation 10s 10.25 both alternate-reverse',
-  });
-  const anim = div.getAnimations()[0];
+test(function(t) {
+  var div = addDiv(t, {style: 'animation: moveAnimation 10s 10.25 both alternate-reverse'});
+  var anim = div.getAnimations()[0];
 
   assert_equals(anim.effect.getComputedTiming().progress, 1.0,
                 'Initial value of progress');
@@ -460,11 +426,9 @@ test(t => {
 }, 'progress of a non-integral repeating animation ' +
    'with alternate-reversing direction');
 
-test(t => {
-  const div = addDiv(t, {
-    style: 'animation: moveAnimation 0s 10.25 both alternate',
-  });
-  const anim = div.getAnimations()[0];
+test(function(t) {
+  var div = addDiv(t, {style: 'animation: moveAnimation 0s 10.25 both alternate'});
+  var anim = div.getAnimations()[0];
 
   assert_equals(anim.effect.getComputedTiming().progress, 0.25,
                 'Initial value of progress');
@@ -480,11 +444,9 @@ test(t => {
 }, 'progress of a non-integral repeating zero-duration animation ' +
    'with alternate direction');
 
-test(t => {
-  const div = addDiv(t, {
-    style: 'animation: moveAnimation 0s 10.25 both alternate-reverse',
-  });
-  const anim = div.getAnimations()[0];
+test(function(t) {
+  var div = addDiv(t, {style: 'animation: moveAnimation 0s 10.25 both alternate-reverse'});
+  var anim = div.getAnimations()[0];
 
   assert_equals(anim.effect.getComputedTiming().progress, 0.75,
                 'Initial value of progress');
@@ -504,30 +466,29 @@ test(t => {
 // --------------------
 // currentIteration
 // --------------------
-
-test(t => {
-  const div = addDiv(t, { style: 'animation: moveAnimation 100s 2s' });
-  const effect = div.getAnimations()[0].effect;
+test(function(t) {
+  var div = addDiv(t, {style: 'animation: moveAnimation 100s 2s'});
+  var effect = div.getAnimations()[0].effect;
   assert_equals(effect.getComputedTiming().currentIteration, null,
                 'Initial value of currentIteration before phase');
 }, 'currentIteration of a new animation with no backwards fill is unresolved ' +
    'in before phase');
 
-test(t => {
-  const div = addDiv(t, { style: 'animation: moveAnimation 100s' });
-  const anim = div.getAnimations()[0];
+test(function(t) {
+  var div = addDiv(t, {style: 'animation: moveAnimation 100s'});
+  var anim = div.getAnimations()[0];
   assert_equals(anim.effect.getComputedTiming().currentIteration, 0,
                 'Initial value of currentIteration');
 }, 'currentIteration of a new animation is zero');
 
-test(t => {
+test(function(t) {
   // Note: FillMode here is "both" because
   // 1. Since this a zero-duration animation, it will already have finished
   //    so it won't be returned by getAnimations() unless it fills forwards.
   // 2. Fill backwards, so the currentIteration (before phase) wouldn't be
   //    unresolved (null value).
-  const div = addDiv(t, { style: 'animation: moveAnimation 0s infinite both' });
-  const anim = div.getAnimations()[0];
+  var div = addDiv(t, {style: 'animation: moveAnimation 0s infinite both'});
+  var anim = div.getAnimations()[0];
 
   assert_equals(anim.effect.getComputedTiming().currentIteration, Infinity,
                 'Initial value of currentIteration in after phase');
@@ -538,9 +499,9 @@ test(t => {
                 'Value of currentIteration count during before phase');
 }, 'currentIteration of an infinitely repeating zero-duration animation');
 
-test(t => {
-  const div = addDiv(t, { style: 'animation: moveAnimation 0s 10.5 both' });
-  const anim = div.getAnimations()[0];
+test(function(t) {
+  var div = addDiv(t, {style: 'animation: moveAnimation 0s 10.5 both'});
+  var anim = div.getAnimations()[0];
 
   // Note: currentIteration = ceil(iteration start + iteration count) - 1
   assert_equals(anim.effect.getComputedTiming().currentIteration, 10,
@@ -552,11 +513,9 @@ test(t => {
                 'Value of currentIteration count during before phase');
 }, 'currentIteration of a finitely repeating zero-duration animation');
 
-test(t => {
-  const div = addDiv(t, {
-    style: 'animation: moveAnimation 100s 5.5 forwards'
-  });
-  const anim = div.getAnimations()[0];
+test(function(t) {
+  var div = addDiv(t, {style: 'animation: moveAnimation 100s 5.5 forwards'});
+  var anim = div.getAnimations()[0];
 
   assert_equals(anim.effect.getComputedTiming().currentIteration, 0,
                 'Initial value of currentIteration');
@@ -571,9 +530,9 @@ test(t => {
                 'Value of currentIteration in after phase');
 }, 'currentIteration of an animation with a non-integral iteration count');
 
-test(t => {
-  const div = addDiv(t, { style: 'animation: moveAnimation 100s 2 forwards' });
-  const anim = div.getAnimations()[0];
+test(function(t) {
+  var div = addDiv(t, {style: 'animation: moveAnimation 100s 2 forwards'});
+  var anim = div.getAnimations()[0];
 
   assert_equals(anim.effect.getComputedTiming().currentIteration, 0,
                 'Initial value of currentIteration');
@@ -583,9 +542,9 @@ test(t => {
                 'Value of currentIteration in after phase');
 }, 'currentIteration of an animation with an integral iteration count');
 
-test(t => {
-  const div = addDiv(t, { style: 'animation: moveAnimation 100s forwards' });
-  const anim = div.getAnimations()[0];
+test(function(t) {
+  var div = addDiv(t, {style: 'animation: moveAnimation 100s forwards'});
+  var anim = div.getAnimations()[0];
   assert_equals(anim.effect.getComputedTiming().currentIteration, 0,
                 'Initial value of currentIteration');
   // Finish
@@ -594,9 +553,9 @@ test(t => {
                 'Value of currentIteration in after phase');
 }, 'currentIteration of an animation with a default iteration count');
 
-test(t => {
-  const div = addDiv(t);
-  const effect = new KeyframeEffect(div, {left: ["0px", "100px"]});
+test(function(t) {
+  var div = addDiv(t);
+  var effect = new KeyframeEffect(div, {left: ["0px", "100px"]});
 
   assert_equals(effect.getComputedTiming().currentIteration, null,
                 'currentIteration for orphaned effect');
diff --git a/LayoutTests/imported/mozilla/css-animations/test_animation-currenttime-expected.txt b/LayoutTests/imported/mozilla/css-animations/test_animation-currenttime-expected.txt
new file mode 100644 (file)
index 0000000..b2b6d40
--- /dev/null
@@ -0,0 +1,18 @@
+
+PASS Sanity test to check round-tripping assigning to new animation's currentTime 
+PASS Skipping forward through animation 
+PASS Skipping backwards through animation 
+PASS Redundant change, before -> active, then back 
+PASS Redundant change, before -> after, then back 
+PASS Redundant change, active -> before, then back 
+PASS Redundant change, active -> after, then back 
+PASS Redundant change, after -> before, then back 
+PASS Redundant change, after -> active, then back 
+PASS Seeking finished -> paused dispatches animationstart 
+PASS Setting currentTime to null 
+PASS Animation.currentTime after pausing 
+PASS Animation.currentTime clamping 
+PASS Animation.currentTime clamping for reversed animation 
+PASS Animation.currentTime after cancelling 
+PASS After aborting a pause when finished, the call to play() should rewind the current time 
+
diff --git a/LayoutTests/imported/mozilla/css-animations/test_animation-currenttime.html b/LayoutTests/imported/mozilla/css-animations/test_animation-currenttime.html
new file mode 100644 (file)
index 0000000..e867fa7
--- /dev/null
@@ -0,0 +1,347 @@
+<!doctype html>
+<html>
+  <head>
+    <meta charset=utf-8>
+    <title>Tests for the effect of setting a CSS animation's
+           Animation.currentTime</title>
+    <style>
+
+.animated-div {
+  margin-left: 10px;
+  /* Make it easier to calculate expected values: */
+  animation-timing-function: linear ! important;
+}
+
+@keyframes anim {
+  from { margin-left: 100px; }
+  to { margin-left: 200px; }
+}
+
+    </style>
+    <script src="../../../resources/testharness.js"></script>
+    <script src="../../../resources/testharnessreport.js"></script>
+    <script src="../resources/testcommon.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script type="text/javascript">
+
+'use strict';
+
+// TODO: We should separate this test(Testing for CSS Animation events /
+// Testing for currentTime of Web Animation).
+// e.g:
+//  CSS Animation events test :
+//    - check the firing an event using Animation.currentTime
+//  The current Time of Web Animation test :
+//    - check an current time value on several situation(init / processing..)
+//    - Based on W3C Spec, check the behavior of setting current time.
+
+// TODO: Once the computedTiming property is implemented, add checks to the
+// checker helpers to ensure that computedTiming's properties are updated as
+// expected.
+// See https://bugzilla.mozilla.org/show_bug.cgi?id=1108055
+
+const CSS_ANIM_EVENTS =
+  ['animationstart', 'animationiteration', 'animationend'];
+
+test(function(t)
+{
+  var div = addDiv(t, {'class': 'animated-div'});
+  div.style.animation = "anim 100s";
+  var animation = div.getAnimations()[0];
+
+  // Animations shouldn't start until the next paint tick, so:
+  assert_equals(animation.currentTime, 0,
+    'Animation.currentTime should be zero when an animation ' +
+    'is initially created');
+
+  // Make sure the animation is running before we set the current time.
+  animation.startTime = animation.timeline.currentTime;
+
+  animation.currentTime = 50 * MS_PER_SEC;
+  assert_time_equals_literal(animation.currentTime, 50 * MS_PER_SEC,
+    'Check setting of currentTime actually works');
+}, 'Sanity test to check round-tripping assigning to new animation\'s ' +
+   'currentTime');
+
+promise_test(function(t) {
+  var div = addDiv(t, {'class': 'animated-div'});
+  var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS);
+  div.style.animation = "anim 100s 100s";
+  var animation = div.getAnimations()[0];
+
+  return animation.ready.then(function() {
+    // the 0.0001 here is for rounding error
+    assert_less_than_equal(animation.currentTime,
+      animation.timeline.currentTime - animation.startTime + 0.0001,
+      'Animation.currentTime should be less than the local time ' +
+      'equivalent of the timeline\'s currentTime on the first paint tick ' +
+      'after animation creation');
+
+    animation.currentTime = 100 * MS_PER_SEC;
+    return eventWatcher.wait_for('animationstart');
+  }).then(function() {
+    animation.currentTime = 200 * MS_PER_SEC;
+    return eventWatcher.wait_for('animationend');
+  });
+}, 'Skipping forward through animation');
+
+promise_test(function(t) {
+  var div = addDiv(t, {'class': 'animated-div'});
+  var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS);
+  div.style.animation = "anim 100s 100s";
+  var animation = div.getAnimations()[0];
+  animation.currentTime = 200 * MS_PER_SEC;
+  var previousTimelineTime = animation.timeline.currentTime;
+
+  return eventWatcher.wait_for(['animationstart',
+                                'animationend']).then(function() {
+    assert_true(document.timeline.currentTime - previousTimelineTime <
+                100 * MS_PER_SEC,
+                'Sanity check that seeking worked rather than the events ' +
+                'firing after normal playback through the very long ' +
+                'animation duration');
+
+    animation.currentTime = 150 * MS_PER_SEC;
+    return eventWatcher.wait_for('animationstart');
+  }).then(function() {
+    animation.currentTime = 0;
+    return eventWatcher.wait_for('animationend');
+  });
+}, 'Skipping backwards through animation');
+
+// Next we have multiple tests to check that redundant currentTime changes do
+// NOT dispatch events. It's impossible to distinguish between events not being
+// dispatched and events just taking an incredibly long time to dispatch
+// without waiting an infinitely long time. Obviously we don't want to do that
+// (block this test from finishing forever), so instead we just listen for
+// events until two animation frames (i.e. requestAnimationFrame callbacks)
+// have happened, then assume that no events will ever be dispatched for the
+// redundant changes if no events were detected in that time.
+
+promise_test(function(t) {
+  var div = addDiv(t, {'class': 'animated-div'});
+  var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS);
+  div.style.animation = "anim 100s 100s";
+  var animation = div.getAnimations()[0];
+
+  animation.currentTime = 150 * MS_PER_SEC;
+  animation.currentTime = 50 * MS_PER_SEC;
+
+  return waitForAnimationFrames(2);
+}, 'Redundant change, before -> active, then back');
+
+promise_test(function(t) {
+  var div = addDiv(t, {'class': 'animated-div'});
+  var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS);
+  div.style.animation = "anim 100s 100s";
+  var animation = div.getAnimations()[0];
+
+  animation.currentTime = 250 * MS_PER_SEC;
+  animation.currentTime = 50 * MS_PER_SEC;
+
+  return waitForAnimationFrames(2);
+}, 'Redundant change, before -> after, then back');
+
+promise_test(function(t) {
+  var div = addDiv(t, {'class': 'animated-div'});
+  var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS);
+  div.style.animation = "anim 100s 100s";
+  var animation = div.getAnimations()[0];
+
+  var retPromise = eventWatcher.wait_for('animationstart').then(function() {
+    animation.currentTime = 50 * MS_PER_SEC;
+    animation.currentTime = 150 * MS_PER_SEC;
+
+    return waitForAnimationFrames(2);
+  });
+  // get us into the initial state:
+  animation.currentTime = 150 * MS_PER_SEC;
+
+  return retPromise;
+}, 'Redundant change, active -> before, then back');
+
+promise_test(function(t) {
+  var div = addDiv(t, {'class': 'animated-div'});
+  var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS);
+  div.style.animation = "anim 100s 100s";
+  var animation = div.getAnimations()[0];
+
+  var retPromise = eventWatcher.wait_for('animationstart').then(function() {
+    animation.currentTime = 250 * MS_PER_SEC;
+    animation.currentTime = 150 * MS_PER_SEC;
+
+    return waitForAnimationFrames(2);
+  });
+  // get us into the initial state:
+  animation.currentTime = 150 * MS_PER_SEC;
+
+  return retPromise;
+}, 'Redundant change, active -> after, then back');
+
+promise_test(function(t) {
+  var div = addDiv(t, {'class': 'animated-div'});
+  var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS);
+  div.style.animation = "anim 100s 100s";
+  var animation = div.getAnimations()[0];
+
+  var retPromise =  eventWatcher.wait_for(['animationstart',
+                                           'animationend']).then(function() {
+    animation.currentTime = 50 * MS_PER_SEC;
+    animation.currentTime = 250 * MS_PER_SEC;
+
+    return waitForAnimationFrames(2);
+  });
+  // get us into the initial state:
+  animation.currentTime = 250 * MS_PER_SEC;
+
+  return retPromise;
+}, 'Redundant change, after -> before, then back');
+
+promise_test(function(t) {
+  var div = addDiv(t, {'class': 'animated-div'});
+  var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS);
+  div.style.animation = "anim 100s 100s";
+  var animation = div.getAnimations()[0];
+
+  var retPromise =  eventWatcher.wait_for(['animationstart',
+                                           'animationend']).then(function() {
+    animation.currentTime = 150 * MS_PER_SEC;
+    animation.currentTime = 250 * MS_PER_SEC;
+
+    return waitForAnimationFrames(2);
+  });
+  // get us into the initial state:
+  animation.currentTime = 250 * MS_PER_SEC;
+
+  return retPromise;
+}, 'Redundant change, after -> active, then back');
+
+promise_test(function(t) {
+  var div = addDiv(t, {'class': 'animated-div'});
+  var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS);
+  div.style.animation = "anim 100s"
+  var animation = div.getAnimations()[0];
+
+  animation.pause();
+  animation.currentTime = 150 * MS_PER_SEC;
+
+  return eventWatcher.wait_for(['animationstart',
+                                'animationend']).then(function() {
+    animation.currentTime = 50 * MS_PER_SEC;
+    return eventWatcher.wait_for('animationstart');
+  });
+}, 'Seeking finished -> paused dispatches animationstart');
+
+promise_test(function(t) {
+  var div = addDiv(t, {'class': 'animated-div'});
+  div.style.animation = "anim 100s";
+
+  var animation = div.getAnimations()[0];
+
+  return animation.ready.then(function() {
+    var exception;
+    try {
+      animation.currentTime = null;
+    } catch (e) {
+      exception = e;
+    }
+    assert_equals(exception.name, 'TypeError',
+      'Expect TypeError exception on trying to set ' +
+      'Animation.currentTime to null');
+  });
+}, 'Setting currentTime to null');
+
+promise_test(function(t) {
+  var div = addDiv(t, {'class': 'animated-div'});
+  div.style.animation = 'anim 100s';
+
+  var animation = div.getAnimations()[0];
+  var pauseTime;
+
+  return animation.ready.then(function() {
+    assert_not_equals(animation.currentTime, null,
+      'Animation.currentTime not null on ready Promise resolve');
+    animation.pause();
+    return animation.ready;
+  }).then(function() {
+    pauseTime = animation.currentTime;
+    return waitForFrame();
+  }).then(function() {
+    assert_equals(animation.currentTime, pauseTime,
+      'Animation.currentTime is unchanged after pausing');
+  });
+}, 'Animation.currentTime after pausing');
+
+promise_test(function(t) {
+  var div = addDiv(t, {'class': 'animated-div'});
+  div.style.animation = "anim 100s";
+  var animation = div.getAnimations()[0];
+
+  return animation.ready.then(function() {
+    // just before animation ends:
+    animation.currentTime = 100 * MS_PER_SEC - 1;
+    return waitForAnimationFrames(2);
+  }).then(function() {
+    assert_equals(animation.currentTime, 100 * MS_PER_SEC,
+      'Animation.currentTime should not continue to increase after the ' +
+      'animation has finished');
+  });
+}, 'Animation.currentTime clamping');
+
+promise_test(function(t) {
+  var div = addDiv(t, {'class': 'animated-div'});
+  div.style.animation = "anim 100s";
+  var animation = div.getAnimations()[0];
+
+  return animation.ready.then(function() {
+    // play backwards:
+    animation.playbackRate = -1;
+
+    // just before animation ends (at the "start"):
+    animation.currentTime = 1;
+
+    return waitForAnimationFrames(2);
+  }).then(function() {
+    assert_equals(animation.currentTime, 0,
+      'Animation.currentTime should not continue to decrease after an ' +
+      'animation running in reverse has finished and currentTime is zero');
+  });
+}, 'Animation.currentTime clamping for reversed animation');
+
+test(function(t) {
+  var div = addDiv(t, {'class': 'animated-div'});
+  div.style.animation = 'anim 100s';
+  var animation = div.getAnimations()[0];
+  animation.cancel();
+
+  assert_equals(animation.currentTime, null,
+                'The currentTime of a cancelled animation should be null');
+}, 'Animation.currentTime after cancelling');
+
+promise_test(function(t) {
+  var div = addDiv(t, {'class': 'animated-div'});
+  div.style.animation = 'anim 100s';
+  var animation = div.getAnimations()[0];
+
+  return animation.ready.then(function() {
+    animation.finish();
+
+    // Initiate a pause then abort it
+    animation.pause();
+    animation.play();
+
+    // Wait to return to running state
+    return animation.ready;
+  }).then(function() {
+    assert_true(animation.currentTime < 100 * 1000,
+                'After aborting a pause when finished, the currentTime should'
+                + ' jump back towards the start of the animation');
+  });
+}, 'After aborting a pause when finished, the call to play() should rewind'
+   + ' the current time');
+
+    </script>
+  </body>
+</html>
diff --git a/LayoutTests/imported/mozilla/css-animations/test_animation-finish-expected.txt b/LayoutTests/imported/mozilla/css-animations/test_animation-finish-expected.txt
new file mode 100644 (file)
index 0000000..5a7cd5f
--- /dev/null
@@ -0,0 +1,6 @@
+
+PASS Test exceptions when finishing infinite animation 
+PASS Test finish() while paused 
+PASS Test finish() while pause-pending with positive playbackRate 
+PASS Test finish() while pause-pending with negative playbackRate 
+
diff --git a/LayoutTests/imported/mozilla/css-animations/test_animation-finish.html b/LayoutTests/imported/mozilla/css-animations/test_animation-finish.html
new file mode 100644 (file)
index 0000000..99ed1f2
--- /dev/null
@@ -0,0 +1,97 @@
+<!doctype html>
+<meta charset=utf-8>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="../resources/testcommon.js"></script>
+<style>
+@keyframes anim {
+  from { margin-left: 100px; }
+  to { margin-left: 200px; }
+}
+</style>
+<body>
+<div id="log"></div>
+<script>
+
+'use strict';
+
+const ANIM_PROP_VAL = 'anim 100s';
+const ANIM_DURATION = 100000; // ms
+
+test(function(t) {
+  var div = addDiv(t);
+  div.style.animation = ANIM_PROP_VAL;
+  div.style.animationIterationCount = 'infinite';
+  var animation = div.getAnimations()[0];
+
+  var threw = false;
+  try {
+    animation.finish();
+  } catch (e) {
+    threw = true;
+    assert_equals(e.name, 'InvalidStateError',
+                  'Exception should be an InvalidStateError exception when ' +
+                  'trying to finish an infinite animation');
+  }
+  assert_true(threw,
+              'Expect InvalidStateError exception trying to finish an ' +
+              'infinite animation');
+}, 'Test exceptions when finishing infinite animation');
+
+async_test(function(t) {
+  var div = addDiv(t);
+  div.style.animation = ANIM_PROP_VAL + ' paused';
+  var animation = div.getAnimations()[0];
+
+  animation.ready.then(t.step_func(function() {
+    animation.finish();
+    assert_equals(animation.playState, 'finished',
+                  'The play state of a paused animation should become ' +
+                  '"finished" after finish() is called');
+    assert_times_equal(animation.startTime,
+                       animation.timeline.currentTime - ANIM_DURATION,
+                       'The start time of a paused animation should be set ' +
+                       'after calling finish()');
+    t.done();
+  }));
+}, 'Test finish() while paused');
+
+test(function(t) {
+  var div = addDiv(t);
+  div.style.animation = ANIM_PROP_VAL + ' paused';
+  var animation = div.getAnimations()[0];
+
+  // Update playbackRate so we can test that the calculated startTime
+  // respects it
+  animation.playbackRate = 2;
+
+  // While animation is still pause-pending call finish()
+  animation.finish();
+
+  assert_equals(animation.playState, 'finished',
+                'The play state of a pause-pending animation should become ' +
+                '"finished" after finish() is called');
+  assert_times_equal(animation.startTime,
+                     animation.timeline.currentTime - ANIM_DURATION / 2,
+                     'The start time of a pause-pending animation should ' +
+                     'be set after calling finish()');
+}, 'Test finish() while pause-pending with positive playbackRate');
+
+test(function(t) {
+  var div = addDiv(t);
+  div.style.animation = ANIM_PROP_VAL + ' paused';
+  var animation = div.getAnimations()[0];
+
+  animation.playbackRate = -2;
+  animation.finish();
+
+  assert_equals(animation.playState, 'finished',
+                'The play state of a pause-pending animation should become ' +
+                '"finished" after finish() is called');
+  assert_equals(animation.startTime, animation.timeline.currentTime,
+                'The start time of a pause-pending animation should be ' +
+                'set after calling finish()');
+}, 'Test finish() while pause-pending with negative playbackRate');
+
+</script>
+</body>
diff --git a/LayoutTests/imported/mozilla/css-animations/test_animation-finished-expected.txt b/LayoutTests/imported/mozilla/css-animations/test_animation-finished-expected.txt
new file mode 100644 (file)
index 0000000..5583223
--- /dev/null
@@ -0,0 +1,5 @@
+
+PASS finished promise is rejected when an animation is cancelled by resetting the animation property 
+PASS finished promise is rejected when an animation is cancelled by changing the animation property 
+PASS Test finished promise changes when animationPlayState set to running 
+
diff --git a/LayoutTests/imported/mozilla/css-animations/test_animation-finished.html b/LayoutTests/imported/mozilla/css-animations/test_animation-finished.html
new file mode 100644 (file)
index 0000000..21b2df0
--- /dev/null
@@ -0,0 +1,95 @@
+<!doctype html>
+<meta charset=utf-8>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="../resources/testcommon.js"></script>
+<style>
+@keyframes abc {
+  to { transform: translate(10px) }
+}
+@keyframes def {}
+</style>
+<body>
+<div id="log"></div>
+<script>
+'use strict';
+
+const ANIM_PROP_VAL = 'abc 100s';
+const ANIM_DURATION = 100 * MS_PER_SEC;
+
+promise_test(function(t) {
+  var div = addDiv(t);
+  // Set up pending animation
+  div.style.animation = ANIM_PROP_VAL;
+  var animation = div.getAnimations()[0];
+  var previousFinishedPromise = animation.finished;
+  // Set up listeners on finished promise
+  var retPromise = animation.finished.then(function() {
+    assert_unreached('finished promise is 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');
+  });
+
+  // Now cancel the animation and flush styles
+  div.style.animation = '';
+  getComputedStyle(div).animation;
+
+  return retPromise;
+}, 'finished promise is rejected when an animation is cancelled by resetting ' +
+   'the animation property');
+
+promise_test(function(t) {
+  var div = addDiv(t);
+  // As before, but this time instead of removing all animations, simply update
+  // the list of animations. At least for Firefox, updating is a different
+  // code path.
+
+  // Set up pending animation
+  div.style.animation = ANIM_PROP_VAL;
+  var animation = div.getAnimations()[0];
+  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');
+  });
+
+  // Now update the animation and flush styles
+  div.style.animation = 'def 100s';
+  getComputedStyle(div).animation;
+
+  return retPromise;
+}, 'finished promise is rejected when an animation is cancelled by changing ' +
+   'the animation property');
+
+promise_test(function(t) {
+  var div = addDiv(t);
+  div.style.animation = ANIM_PROP_VAL;
+  var animation = div.getAnimations()[0];
+  var previousFinishedPromise = animation.finished;
+  animation.currentTime = ANIM_DURATION;
+  return animation.finished.then(function() {
+    div.style.animationPlayState = 'running';
+    return waitForAnimationFrames(2);
+  }).then(function() {
+    assert_equals(animation.finished, previousFinishedPromise,
+                  'Should not replay when animation-play-state changes to ' +
+                  '"running" on finished animation');
+    assert_equals(animation.currentTime, ANIM_DURATION,
+                  'currentTime should not change when animation-play-state ' +
+                  'changes to "running" on finished animation');
+  });
+}, 'Test finished promise changes when animationPlayState set to running');
+
+</script>
+</body>
diff --git a/LayoutTests/imported/mozilla/css-animations/test_animation-id.html b/LayoutTests/imported/mozilla/css-animations/test_animation-id.html
new file mode 100644 (file)
index 0000000..e7bb605
--- /dev/null
@@ -0,0 +1,26 @@
+<!doctype html>
+<meta charset=utf-8>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="../resources/testcommon.js"></script>
+<style>
+@keyframes abc { }
+</style>
+<body>
+<div id="log"></div>
+<script>
+'use strict';
+
+test(function(t) {
+  var div = addDiv(t);
+  div.style.animation = 'abc 100s';
+  var animation = div.getAnimations()[0];
+  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>
+</html>
diff --git a/LayoutTests/imported/mozilla/css-animations/test_animation-pausing.html b/LayoutTests/imported/mozilla/css-animations/test_animation-pausing.html
new file mode 100644 (file)
index 0000000..00c66df
--- /dev/null
@@ -0,0 +1,168 @@
+<!doctype html>
+<meta charset=utf-8>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="../resources/testcommon.js"></script>
+<style>
+@keyframes anim {
+  0% { margin-left: 0px }
+  100% { margin-left: 10000px }
+}
+</style>
+<body>
+<div id="log"></div>
+<script>
+'use strict';
+
+function getMarginLeft(cs) {
+  return parseFloat(cs.marginLeft);
+}
+
+promise_test(function(t) {
+  var div = addDiv(t);
+  var cs = getComputedStyle(div);
+  div.style.animation = 'anim 1000s paused';
+  var animation = div.getAnimations()[0];
+  assert_equals(getMarginLeft(cs), 0,
+                'Initial value of margin-left is zero');
+  animation.play();
+
+  return animation.ready.then(waitForNextFrame).then(function() {
+    assert_greater_than(getMarginLeft(cs), 0,
+                        'Playing value of margin-left is greater than zero');
+  });
+}, 'play() overrides animation-play-state');
+
+promise_test(function(t) {
+  var div = addDiv(t);
+  var cs = getComputedStyle(div);
+  div.style.animation = 'anim 1000s paused';
+  var animation = div.getAnimations()[0];
+  assert_equals(getMarginLeft(cs), 0,
+                'Initial value of margin-left is zero');
+
+  animation.pause();
+  div.style.animationPlayState = 'running';
+
+  return animation.ready.then(waitForNextFrame).then(function() {
+    assert_equals(cs.animationPlayState, 'running',
+                  'animation-play-state is running');
+    assert_equals(getMarginLeft(cs), 0,
+                  'Paused value of margin-left is zero');
+  });
+}, 'pause() overrides animation-play-state');
+
+promise_test(function(t) {
+  var div = addDiv(t);
+  var cs = getComputedStyle(div);
+  div.style.animation = 'anim 1000s paused';
+  var animation = div.getAnimations()[0];
+  assert_equals(getMarginLeft(cs), 0,
+                'Initial value of margin-left is zero');
+  animation.play();
+  var previousAnimVal;
+
+  return animation.ready.then(function() {
+    div.style.animationPlayState = 'running';
+    cs.animationPlayState; // Trigger style resolution
+    return waitForNextFrame();
+  }).then(function() {
+    assert_equals(cs.animationPlayState, 'running',
+                  'animation-play-state is running');
+    div.style.animationPlayState = 'paused';
+    return animation.ready;
+  }).then(function() {
+    assert_equals(cs.animationPlayState, 'paused',
+                  'animation-play-state is paused');
+    previousAnimVal = getMarginLeft(cs);
+    return waitForNextFrame();
+  }).then(function() {
+    assert_equals(getMarginLeft(cs), previousAnimVal,
+                  'Animated value of margin-left does not change when'
+                  + ' paused by style');
+  });
+}, 'play() is overridden by later setting "animation-play-state: paused"');
+
+promise_test(function(t) {
+  var div = addDiv(t);
+  var cs = getComputedStyle(div);
+  div.style.animation = 'anim 1000s';
+  var animation = div.getAnimations()[0];
+  assert_equals(getMarginLeft(cs), 0,
+                'Initial value of margin-left is zero');
+
+  // Set the specified style first. If implementations fail to
+  // apply the style changes first, they will ignore the redundant
+  // call to play() and fail to correctly override the pause style.
+  div.style.animationPlayState = 'paused';
+  animation.play();
+  var previousAnimVal = getMarginLeft(cs);
+
+  return animation.ready.then(waitForNextFrame).then(function() {
+    assert_equals(cs.animationPlayState, 'paused',
+                  'animation-play-state is paused');
+    assert_greater_than(getMarginLeft(cs), previousAnimVal,
+                        'Playing value of margin-left is increasing');
+  });
+}, 'play() flushes pending changes to animation-play-state first');
+
+promise_test(function(t) {
+  var div = addDiv(t);
+  var cs = getComputedStyle(div);
+  div.style.animation = 'anim 1000s paused';
+  var animation = div.getAnimations()[0];
+  assert_equals(getMarginLeft(cs), 0,
+                'Initial value of margin-left is zero');
+
+  // Unlike the previous test for play(), since calling pause() is sticky,
+  // we'll apply it even if the underlying style also says we're paused.
+  //
+  // We would like to test that implementations flush styles before running
+  // pause() but actually there's no style we can currently set that will
+  // change the behavior of pause(). That may change in the future
+  // (e.g. if we introduce animation-timeline or animation-playback-rate etc.).
+  //
+  // For now this just serves as a sanity check that we do the same thing
+  // even if we set style before calling the API.
+  div.style.animationPlayState = 'running';
+  animation.pause();
+  var previousAnimVal = getMarginLeft(cs);
+
+  return animation.ready.then(waitForNextFrame).then(function() {
+    assert_equals(cs.animationPlayState, 'running',
+                  'animation-play-state is running');
+    assert_equals(getMarginLeft(cs), previousAnimVal,
+                  'Paused value of margin-left does not change');
+  });
+}, 'pause() applies pending changes to animation-play-state first');
+// (Note that we can't actually test for this; see comment above, in test-body.)
+
+promise_test(function(t) {
+  var div = addDiv(t, { style: 'animation: anim 1000s' });
+  var animation = div.getAnimations()[0];
+  var readyPromiseRun = false;
+
+  return animation.ready.then(function() {
+    div.style.animationPlayState = 'paused';
+    assert_true(animation.pending && animation.playState === 'paused',
+                'Animation is pause-pending');
+
+    // Set current time
+    animation.currentTime = 5 * MS_PER_SEC;
+    assert_equals(animation.playState, 'paused',
+                  'Animation is paused immediately after setting currentTime');
+    assert_equals(animation.startTime, null,
+                  'Animation startTime is unresolved immediately after ' +
+                  'setting currentTime');
+    assert_equals(animation.currentTime, 5 * MS_PER_SEC,
+                  'Animation currentTime does not change when forcing a ' +
+                  'pause operation to complete');
+
+    // The ready promise should now be resolved. If it's not then test will
+    // probably time out before anything else happens that causes it to resolve.
+    return animation.ready;
+  });
+}, 'Setting the current time completes a pending pause');
+
+</script>
+</body>
@@ -1,7 +1,7 @@
 
-PASS A new CSS animation is initially play-pending 
+PASS Animation returns correct playState when running 
 PASS Animation returns correct playState when paused 
 PASS Animation.playState updates when paused by script 
 PASS Animation.playState updates when resumed by setting style 
-PASS Animation returns correct playState when canceled 
+PASS Animation returns correct playState when cancelled 
 
diff --git a/LayoutTests/imported/mozilla/css-animations/test_animation-playstate.html b/LayoutTests/imported/mozilla/css-animations/test_animation-playstate.html
new file mode 100644 (file)
index 0000000..562f766
--- /dev/null
@@ -0,0 +1,61 @@
+<!doctype html>
+<meta charset=utf-8>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="../resources/testcommon.js"></script>
+<style>
+@keyframes anim { }
+</style>
+<body>
+<div id="log"></div>
+<script>
+'use strict';
+
+test(function(t) {
+  var div = addDiv(t);
+  var cs = getComputedStyle(div);
+  div.style.animation = 'anim 1000s';
+  var animation = div.getAnimations()[0];
+  assert_equals(animation.playState, 'running');
+}, 'Animation returns correct playState when running');
+
+test(function(t) {
+  var div = addDiv(t);
+  var cs = getComputedStyle(div);
+  div.style.animation = 'anim 1000s paused';
+  var animation = div.getAnimations()[0];
+  assert_equals(animation.playState, 'paused');
+}, 'Animation returns correct playState when paused');
+
+test(function(t) {
+  var div = addDiv(t);
+  var cs = getComputedStyle(div);
+  div.style.animation = 'anim 1000s';
+  var animation = div.getAnimations()[0];
+  animation.pause();
+  assert_equals(animation.playState, 'paused');
+}, 'Animation.playState updates when paused by script');
+
+test(function(t) {
+  var div = addDiv(t);
+  var cs = getComputedStyle(div);
+  div.style.animation = 'anim 1000s paused';
+  var animation = div.getAnimations()[0];
+  div.style.animationPlayState = 'running';
+
+  // This test also checks that calling playState flushes style
+  assert_equals(animation.playState, 'running',
+                'Animation.playState reports running after updating'
+                + ' animation-play-state (got: ' + animation.playState + ')');
+}, 'Animation.playState updates when resumed by setting style');
+
+test(function(t) {
+  var div = addDiv(t);
+  div.style.animation = 'anim 1000s';
+  var animation = div.getAnimations()[0];
+  animation.cancel();
+  assert_equals(animation.playState, 'idle');
+}, 'Animation returns correct playState when cancelled');
+
+</script>
+</body>
@@ -1,7 +1,9 @@
 
 PASS A new ready promise is created when setting animation-play-state: running 
 PASS ready promise is rejected when an animation is canceled by resetting the animation property 
-PASS ready promise is rejected when an animation is canceled by updating the animation property 
+PASS ready promise is rejected when an animation is cancelled by updating the animation property 
 PASS A new ready promise is created when setting animation-play-state: paused 
 PASS Pausing twice re-uses the same Promise 
+PASS If a pause operation is interrupted, the ready promise is reused 
+PASS When a pause is complete the Promise callback gets the correct animation 
 
diff --git a/LayoutTests/imported/mozilla/css-animations/test_animation-ready.html b/LayoutTests/imported/mozilla/css-animations/test_animation-ready.html
new file mode 100644 (file)
index 0000000..cec2bdb
--- /dev/null
@@ -0,0 +1,149 @@
+<!doctype html>
+<meta charset=utf-8>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="../resources/testcommon.js"></script>
+<style>
+@keyframes abc {
+  to { transform: translate(10px) }
+}
+</style>
+<body>
+<div id="log"></div>
+<script>
+'use strict';
+
+promise_test(function(t) {
+  var div = addDiv(t);
+  div.style.animation = 'abc 100s paused';
+  var animation = div.getAnimations()[0];
+  var originalReadyPromise = animation.ready;
+
+  return animation.ready.then(function() {
+    div.style.animationPlayState = 'running';
+    assert_not_equals(animation.ready, originalReadyPromise,
+                      'After updating animation-play-state a new ready promise'
+                      + ' object is created');
+  });
+}, 'A new ready promise is created when setting animation-play-state: running');
+
+promise_test(function(t) {
+  var div = addDiv(t);
+
+  // Set up pending animation
+  div.style.animation = 'abc 100s';
+  var animation = div.getAnimations()[0];
+  assert_true(animation.pending, 'Animation is initially pending');
+
+  // Set up listeners on ready promise
+  var retPromise = animation.ready.then(function() {
+    assert_unreached('ready promise is fulfilled');
+  }).catch(function(err) {
+    assert_equals(err.name, 'AbortError',
+                  'ready promise is rejected with AbortError');
+  });
+
+  // Now cancel the animation and flush styles
+  div.style.animation = '';
+  getComputedStyle(div).animation;
+
+  return retPromise;
+}, 'ready promise is rejected when an animation is canceled by resetting'
+   + ' the animation property');
+
+promise_test(function(t) {
+  var div = addDiv(t);
+
+  // As before, but this time instead of removing all animations, simply update
+  // the list of animations. At least for Firefox, updating is a different
+  // code path.
+
+  // Set up pending animation
+  div.style.animation = 'abc 100s';
+  var animation = div.getAnimations()[0];
+  assert_true(animation.pending, 'Animation is initially pending');
+
+  // Set up listeners on 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');
+  });
+
+  // Now update the animation and flush styles
+  div.style.animation = 'def 100s';
+  getComputedStyle(div).animation;
+
+  return retPromise;
+}, 'ready promise is rejected when an animation is cancelled by updating'
+   + ' the animation property');
+
+promise_test(function(t) {
+  var div = addDiv(t, { style: 'animation: abc 100s' });
+  var animation = div.getAnimations()[0];
+  var originalReadyPromise = animation.ready;
+
+  return animation.ready.then(function() {
+    div.style.animationPlayState = 'paused';
+    assert_not_equals(animation.ready, originalReadyPromise,
+                      'A new Promise object is generated when setting'
+                      + ' animation-play-state: paused');
+  });
+}, 'A new ready promise is created when setting animation-play-state: paused');
+
+promise_test(function(t) {
+  var div = addDiv(t, { style: 'animation: abc 100s' });
+  var animation = div.getAnimations()[0];
+
+  return animation.ready.then(function() {
+    div.style.animationPlayState = 'paused';
+    var firstReadyPromise = animation.ready;
+    animation.pause();
+    assert_equals(animation.ready, firstReadyPromise,
+                  'Ready promise objects are identical after redundant pause');
+  });
+}, 'Pausing twice re-uses the same Promise');
+
+promise_test(function(t) {
+  var div = addDiv(t, { style: 'animation: abc 100s' });
+  var animation = div.getAnimations()[0];
+
+  return animation.ready.then(function() {
+    div.style.animationPlayState = 'paused';
+
+    // Flush style and verify we're pending at the same time
+    assert_true(animation.pending, 'Animation is pending');
+    var pauseReadyPromise = animation.ready;
+
+    // Now play again immediately
+    div.style.animationPlayState = 'running';
+    assert_true(animation.pending, 'Animation is still pending');
+    assert_equals(animation.ready, pauseReadyPromise,
+                  'The pause Promise is re-used when playing while waiting'
+                  + ' to pause');
+
+    return animation.ready;
+  }).then(function() {
+    assert_true(!animation.pending && animation.playState === 'running',
+                'Animation is running after aborting a pause');
+  });
+}, 'If a pause operation is interrupted, the ready promise is reused');
+
+promise_test(function(t) {
+  var div = addDiv(t, { style: 'animation: abc 100s' });
+  var animation = div.getAnimations()[0];
+
+  return animation.ready.then(function() {
+    div.style.animationPlayState = 'paused';
+    return animation.ready;
+  }).then(function(resolvedAnimation) {
+    assert_equals(resolvedAnimation, animation,
+                  'Promise received when ready Promise for a pause operation'
+                  + ' is completed is the animation on which the pause was'
+                  + ' performed');
+  });
+}, 'When a pause is complete the Promise callback gets the correct animation');
+
+</script>
+</body>
diff --git a/LayoutTests/imported/mozilla/css-animations/test_animation-reverse-expected.txt b/LayoutTests/imported/mozilla/css-animations/test_animation-reverse-expected.txt
new file mode 100644 (file)
index 0000000..7656fc4
--- /dev/null
@@ -0,0 +1,3 @@
+
+PASS reverse() from idle state starts playing the animation 
+
diff --git a/LayoutTests/imported/mozilla/css-animations/test_animation-reverse.html b/LayoutTests/imported/mozilla/css-animations/test_animation-reverse.html
new file mode 100644 (file)
index 0000000..2f4a841
--- /dev/null
@@ -0,0 +1,30 @@
+<!doctype html>
+<meta charset=utf-8>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="../resources/testcommon.js"></script>
+<style>
+@keyframes anim {
+  to { transform: translate(100px) }
+}
+</style>
+<body>
+<div id="log"></div>
+<script>
+'use strict';
+
+test(function(t) {
+  var div = addDiv(t, { style: 'animation: anim 100s' });
+  var animation = div.getAnimations()[0];
+  div.style.animation = "";
+  flushComputedStyle(div);
+
+  assert_equals(animation.currentTime, null);
+  animation.reverse();
+
+  assert_equals(animation.currentTime, 100 * MS_PER_SEC,
+    'animation.currentTime should be its effect end');
+}, 'reverse() from idle state starts playing the animation');
+
+</script>
+</body>
diff --git a/LayoutTests/imported/mozilla/css-animations/test_animation-starttime-expected.txt b/LayoutTests/imported/mozilla/css-animations/test_animation-starttime-expected.txt
new file mode 100644 (file)
index 0000000..b98c9d1
--- /dev/null
@@ -0,0 +1,22 @@
+
+PASS startTime of a newly created (play-pending) animation is unresolved 
+PASS startTime of a newly created (pause-pending) animation is unresolved 
+PASS startTime is resolved when running 
+PASS startTime is unresolved when paused 
+PASS startTime while pause-pending and play-pending 
+PASS startTime while play-pending from finished state 
+PASS startTime while play-pending from finished state using finish() 
+PASS Pausing should make the startTime become null 
+PASS Sanity test to check round-tripping assigning to a new animation's startTime 
+PASS Skipping forward through animation 
+PASS Skipping backwards through animation 
+PASS Redundant change, before -> active, then back 
+PASS Redundant change, before -> after, then back 
+PASS Redundant change, active -> before, then back 
+PASS Redundant change, active -> after, then back 
+PASS Redundant change, after -> before, then back 
+PASS Redundant change, after -> active, then back 
+PASS Setting startTime to null 
+PASS Animation.startTime after pausing 
+PASS Animation.startTime after cancelling 
+
diff --git a/LayoutTests/imported/mozilla/css-animations/test_animation-starttime.html b/LayoutTests/imported/mozilla/css-animations/test_animation-starttime.html
new file mode 100644 (file)
index 0000000..6ceb8ab
--- /dev/null
@@ -0,0 +1,385 @@
+<!doctype html>
+<html>
+  <head>
+    <meta charset=utf-8>
+    <title>Tests for the effect of setting a CSS animation's
+           Animation.startTime</title>
+    <style>
+
+.animated-div {
+  margin-left: 10px;
+  /* Make it easier to calculate expected values: */
+  animation-timing-function: linear ! important;
+}
+
+@keyframes anim {
+  from { margin-left: 100px; }
+  to { margin-left: 200px; }
+}
+
+    </style>
+    <script src="../../../resources/testharness.js"></script>
+    <script src="../../../resources/testharnessreport.js"></script>
+    <script src="../resources/testcommon.js"></script>
+  </head>
+  <body>
+    <div id="log"></div>
+    <script type="text/javascript">
+
+'use strict';
+
+// TODO: We should separate this test(Testing for CSS Animation events /
+// Testing for start time of Web Animation).
+// e.g:
+//  CSS Animation events test:
+//    - check the firing an event after setting an Animation.startTime
+//  The start time of Web Animation test:
+//    - check an start time value on several situation(init / processing..)
+//    - Based on W3C Spec, check the behavior of setting current time.
+
+// TODO: Once the computedTiming property is implemented, add checks to the
+// checker helpers to ensure that computedTiming's properties are updated as
+// expected.
+// See https://bugzilla.mozilla.org/show_bug.cgi?id=1108055
+
+const CSS_ANIM_EVENTS =
+  ['animationstart', 'animationiteration', 'animationend'];
+
+test(function(t)
+{
+  var div = addDiv(t, { 'style': 'animation: anim 100s' });
+  var animation = div.getAnimations()[0];
+
+  assert_equals(animation.startTime, null, 'startTime is unresolved');
+}, 'startTime of a newly created (play-pending) animation is unresolved');
+
+test(function(t)
+{
+  var div = addDiv(t, { 'style': 'animation: anim 100s paused' });
+  var animation = div.getAnimations()[0];
+  assert_equals(animation.startTime, null, 'startTime is unresolved');
+}, 'startTime of a newly created (pause-pending) animation is unresolved');
+
+promise_test(function(t)
+{
+  var div = addDiv(t, { 'style': 'animation: anim 100s' });
+  var animation = div.getAnimations()[0];
+
+  return animation.ready.then(function() {
+    assert_true(animation.startTime > 0,
+                'startTime is resolved when running');
+  });
+}, 'startTime is resolved when running');
+
+promise_test(function(t)
+{
+  var div = addDiv(t, { 'style': 'animation: anim 100s paused' });
+  var animation = div.getAnimations()[0];
+
+  return animation.ready.then(function() {
+    assert_equals(animation.startTime, null,
+                  'startTime is unresolved when paused');
+  });
+}, 'startTime is unresolved when paused');
+
+promise_test(function(t)
+{
+  var div = addDiv(t, { 'style': 'animation: anim 100s' });
+  var animation = div.getAnimations()[0];
+
+  return animation.ready.then(function() {
+    div.style.animationPlayState = 'paused';
+    getComputedStyle(div).animationPlayState;
+
+    assert_not_equals(animation.startTime, null,
+                      'startTime is resolved when pause-pending');
+
+    div.style.animationPlayState = 'running';
+    getComputedStyle(div).animationPlayState;
+
+    assert_not_equals(animation.startTime, null,
+                      'startTime is preserved when a pause is aborted');
+  });
+}, 'startTime while pause-pending and play-pending');
+
+promise_test(function(t) {
+  var div = addDiv(t, { 'style': 'animation: anim 100s' });
+  var animation = div.getAnimations()[0];
+  // Seek to end to put us in the finished state
+  animation.currentTime = 100 * MS_PER_SEC;
+
+  return animation.ready.then(function() {
+    // Call play() which puts us back in the running state
+    animation.play();
+
+    assert_equals(animation.startTime, null, 'startTime is unresolved');
+  });
+}, 'startTime while play-pending from finished state');
+
+test(function(t) {
+  var div = addDiv(t, { 'style': 'animation: anim 100s' });
+  var animation = div.getAnimations()[0];
+  animation.finish();
+  // Call play() which puts us back in the running state
+  animation.play();
+
+  assert_equals(animation.startTime, null, 'startTime is unresolved');
+}, 'startTime while play-pending from finished state using finish()');
+
+promise_test(function(t) {
+  var div = addDiv(t, { style: 'animation: anim 100s' });
+  var animation = div.getAnimations()[0];
+
+  assert_equals(animation.startTime, null, 'The initial startTime is null');
+  var initialTimelineTime = document.timeline.currentTime;
+
+  return animation.ready.then(function() {
+    assert_true(animation.startTime > initialTimelineTime,
+                'After the animation has started, startTime is greater than ' +
+                'the time when it was started');
+    var startTimeBeforePausing = animation.startTime;
+
+    div.style.animationPlayState = 'paused';
+    // Flush styles just in case querying animation.startTime doesn't flush
+    // styles (which would be a bug in of itself and could mask a further bug
+    // by causing startTime to appear to not change).
+    getComputedStyle(div).animationPlayState;
+
+    assert_equals(animation.startTime, startTimeBeforePausing,
+                  'The startTime does not change when pausing-pending');
+    return animation.ready;
+  }).then(function() {
+    assert_equals(animation.startTime, null,
+                  'After actually pausing, the startTime of an animation ' +
+                  'is null');
+  });
+}, 'Pausing should make the startTime become null');
+
+test(function(t)
+{
+  var div = addDiv(t, {'class': 'animated-div'});
+  div.style.animation = 'anim 100s 100s';
+  var animation = div.getAnimations()[0];
+  var currentTime = animation.timeline.currentTime;
+  animation.startTime = currentTime;
+
+  assert_times_equal(animation.startTime, currentTime,
+    'Check setting of startTime actually works');
+}, 'Sanity test to check round-tripping assigning to a new animation\'s ' +
+   'startTime');
+
+promise_test(function(t) {
+  var div = addDiv(t, {'class': 'animated-div'});
+  var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS);
+  div.style.animation = 'anim 100s 100s';
+  var animation = div.getAnimations()[0];
+
+  return animation.ready.then(function() {
+    assert_less_than_equal(animation.startTime, animation.timeline.currentTime,
+      'Animation.startTime should be less than the timeline\'s ' +
+      'currentTime on the first paint tick after animation creation');
+
+    animation.startTime = animation.timeline.currentTime - 100 * MS_PER_SEC;
+    return eventWatcher.wait_for('animationstart');
+  }).then(function() {
+    animation.startTime = animation.timeline.currentTime - 200 * MS_PER_SEC;
+    return eventWatcher.wait_for('animationend');
+  });
+}, 'Skipping forward through animation');
+
+promise_test(function(t) {
+  var div = addDiv(t, {'class': 'animated-div'});
+  var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS);
+  div.style.animation = 'anim 100s 100s';
+  var animation = div.getAnimations()[0];
+  animation.startTime = animation.timeline.currentTime - 200 * MS_PER_SEC;
+  var previousTimelineTime = animation.timeline.currentTime;
+
+  return eventWatcher.wait_for(['animationstart',
+                                'animationend']).then(function() {
+    assert_true(document.timeline.currentTime - previousTimelineTime <
+                  100 * MS_PER_SEC,
+                'Sanity check that seeking worked rather than the events ' +
+                'firing after normal playback through the very long ' +
+                'animation duration');
+
+    animation.startTime = animation.timeline.currentTime - 150 * MS_PER_SEC;
+
+    // Despite going backwards from after the end of the animation (to being
+    // in the active interval), we now expect an 'animationstart' event
+    // because the animation should go from being inactive to active.
+    return eventWatcher.wait_for('animationstart');
+  }).then(function() {
+    animation.startTime = animation.timeline.currentTime;
+
+    // Despite going backwards from just after the active interval starts to
+    // the animation start time, we now expect an animationend event
+    // because we went from inside to outside the active interval.
+    return eventWatcher.wait_for('animationend');
+  }).then(function() {
+    assert_less_than_equal(animation.startTime, animation.timeline.currentTime,
+      'Animation.startTime should be less than the timeline\'s ' +
+      'currentTime on the first paint tick after animation creation');
+  });
+}, 'Skipping backwards through animation');
+
+// Next we have multiple tests to check that redundant startTime changes do NOT
+// dispatch events. It's impossible to distinguish between events not being
+// dispatched and events just taking an incredibly long time to dispatch
+// without waiting an infinitely long time. Obviously we don't want to do that
+// (block this test from finishing forever), so instead we just listen for
+// events until two animation frames (i.e. requestAnimationFrame callbacks)
+// have happened, then assume that no events will ever be dispatched for the
+// redundant changes if no events were detected in that time.
+
+promise_test(function(t) {
+  var div = addDiv(t, {'class': 'animated-div'});
+  var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS);
+  div.style.animation = "anim 100s 100s";
+  var animation = div.getAnimations()[0];
+
+  animation.startTime = animation.timeline.currentTime - 150 * MS_PER_SEC;
+  animation.startTime = animation.timeline.currentTime - 50 * MS_PER_SEC;
+
+  return waitForAnimationFrames(2);
+}, 'Redundant change, before -> active, then back');
+
+promise_test(function(t) {
+  var div = addDiv(t, {'class': 'animated-div'});
+  var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS);
+  div.style.animation = "anim 100s 100s";
+  var animation = div.getAnimations()[0];
+
+  animation.startTime = animation.timeline.currentTime - 250 * MS_PER_SEC;
+  animation.startTime = animation.timeline.currentTime - 50 * MS_PER_SEC;
+
+  return waitForAnimationFrames(2);
+}, 'Redundant change, before -> after, then back');
+
+promise_test(function(t) {
+  var div = addDiv(t, {'class': 'animated-div'});
+  var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS);
+  div.style.animation = "anim 100s 100s";
+  var animation = div.getAnimations()[0];
+
+  var retPromise =  eventWatcher.wait_for('animationstart').then(function() {
+    animation.startTime = animation.timeline.currentTime - 50 * MS_PER_SEC;
+    animation.startTime = animation.timeline.currentTime - 150 * MS_PER_SEC;
+
+    return waitForAnimationFrames(2);
+  });
+  // get us into the initial state:
+  animation.startTime = animation.timeline.currentTime - 150 * MS_PER_SEC;
+
+  return retPromise;
+}, 'Redundant change, active -> before, then back');
+
+promise_test(function(t) {
+  var div = addDiv(t, {'class': 'animated-div'});
+  var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS);
+  div.style.animation = "anim 100s 100s";
+  var animation = div.getAnimations()[0];
+
+  var retPromise = eventWatcher.wait_for('animationstart').then(function() {
+    animation.startTime = animation.timeline.currentTime - 250 * MS_PER_SEC;
+    animation.startTime = animation.timeline.currentTime - 150 * MS_PER_SEC;
+
+    return waitForAnimationFrames(2);
+  });
+  // get us into the initial state:
+  animation.startTime = animation.timeline.currentTime - 150 * MS_PER_SEC;
+
+  return retPromise;
+}, 'Redundant change, active -> after, then back');
+
+promise_test(function(t) {
+  var div = addDiv(t, {'class': 'animated-div'});
+  var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS);
+  div.style.animation = "anim 100s 100s";
+  var animation = div.getAnimations()[0];
+
+  var retPromise = eventWatcher.wait_for(['animationstart',
+                                          'animationend']).then(function() {
+    animation.startTime = animation.timeline.currentTime - 50 * MS_PER_SEC;
+    animation.startTime = animation.timeline.currentTime - 250 * MS_PER_SEC;
+
+    return waitForAnimationFrames(2);
+  });
+  // get us into the initial state:
+  animation.startTime = animation.timeline.currentTime - 250 * MS_PER_SEC;
+
+  return retPromise;
+}, 'Redundant change, after -> before, then back');
+
+promise_test(function(t) {
+  var div = addDiv(t, {'class': 'animated-div'});
+  var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS);
+  div.style.animation = "anim 100s 100s";
+  var animation = div.getAnimations()[0];
+
+  var retPromise = eventWatcher.wait_for(['animationstart',
+                                          'animationend']).then(function() {
+    animation.startTime = animation.timeline.currentTime - 150 * MS_PER_SEC;
+    animation.startTime = animation.timeline.currentTime - 250 * MS_PER_SEC;
+
+    return waitForAnimationFrames(2);
+
+  });
+  // get us into the initial state:
+  animation.startTime = animation.timeline.currentTime - 250 * MS_PER_SEC;
+
+  return retPromise;
+}, 'Redundant change, after -> active, then back');
+
+promise_test(function(t) {
+  var div = addDiv(t, {'class': 'animated-div'});
+  div.style.animation = 'anim 100s 100s';
+  var animation = div.getAnimations()[0];
+  var storedCurrentTime;
+
+  return animation.ready.then(function() {
+    storedCurrentTime = animation.currentTime;
+    animation.startTime = null;
+    return animation.ready;
+  }).then(function() {
+    assert_equals(animation.currentTime, storedCurrentTime,
+      'Test that hold time is correct');
+  });
+}, 'Setting startTime to null');
+
+promise_test(function(t) {
+  var div = addDiv(t, {'class': 'animated-div'});
+  div.style.animation = 'anim 100s';
+  var animation = div.getAnimations()[0];
+
+  return animation.ready.then(function() {
+    var savedStartTime = animation.startTime;
+
+    assert_not_equals(animation.startTime, null,
+      'Animation.startTime not null on ready Promise resolve');
+
+    animation.pause();
+    return animation.ready;
+  }).then(function() {
+    assert_equals(animation.startTime, null,
+      'Animation.startTime is null after paused');
+    assert_equals(animation.playState, 'paused',
+      'Animation.playState is "paused" after pause() call');
+  });
+}, 'Animation.startTime after pausing');
+
+promise_test(function(t) {
+  var div = addDiv(t, {'class': 'animated-div'});
+  div.style.animation = 'anim 100s';
+  var animation = div.getAnimations()[0];
+
+  return animation.ready.then(function() {
+    animation.cancel();
+    assert_equals(animation.startTime, null,
+                  'The startTime of a cancelled animation should be null');
+  });
+}, 'Animation.startTime after cancelling');
+
+    </script>
+  </body>
+</html>
diff --git a/LayoutTests/imported/mozilla/css-animations/test_animations-dynamic-changes.html b/LayoutTests/imported/mozilla/css-animations/test_animations-dynamic-changes.html
new file mode 100644 (file)
index 0000000..d213b09
--- /dev/null
@@ -0,0 +1,158 @@
+<!doctype html>
+<meta charset=utf-8>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="../resources/testcommon.js"></script>
+<style>
+@keyframes anim1 {
+  to { left: 100px }
+}
+@keyframes anim2 { }
+</style>
+<body>
+<div id="log"></div>
+<script>
+'use strict';
+
+promise_test(function(t) {
+  var div = addDiv(t);
+  div.style.animation = 'anim1 100s';
+  var originalAnimation = div.getAnimations()[0];
+  var originalStartTime;
+  var originalCurrentTime;
+
+  // Wait a moment so we can confirm the startTime doesn't change (and doesn't
+  // simply reflect the current time).
+  return originalAnimation.ready.then(function() {
+    originalStartTime = originalAnimation.startTime;
+    originalCurrentTime = originalAnimation.currentTime;
+
+    // Wait a moment so we can confirm the startTime doesn't change (and
+    // doesn't simply reflect the current time).
+    return waitForNextFrame();
+  }).then(function() {
+    div.style.animationDuration = '200s';
+    var animation = div.getAnimations()[0];
+    assert_equals(animation, originalAnimation,
+                  'The same Animation is returned after updating'
+                  + ' animation duration');
+    assert_equals(animation.startTime, originalStartTime,
+                  'Animations returned by getAnimations preserve'
+                  + ' their startTime even when they are updated');
+    // Sanity check
+    assert_not_equals(animation.currentTime, originalCurrentTime,
+                      'Animation.currentTime has updated in next'
+                      + ' requestAnimationFrame callback');
+  });
+}, 'Animations preserve their startTime when changed');
+
+test(function(t) {
+  var div = addDiv(t);
+  div.style.animation = 'anim1 100s, anim1 100s';
+
+  // Store original state
+  var animations = div.getAnimations();
+  var animation1 = animations[0];
+  var animation2 = animations[1];
+
+  // Update first in list
+  div.style.animationDuration = '200s, 100s';
+  animations = div.getAnimations();
+  assert_equals(animations[0], animation1,
+                'First Animation is in same position after update');
+  assert_equals(animations[1], animation2,
+                'Second Animation is in same position after update');
+}, 'Updated Animations maintain their order in the list');
+
+promise_test(function(t) {
+  var div = addDiv(t);
+  div.style.animation = 'anim1 200s, anim1 100s';
+
+  // Store original state
+  var animations = div.getAnimations();
+  var animation1 = animations[0];
+  var animation2 = animations[1];
+
+  // Wait before continuing so we can compare start times (otherwise the
+  // new Animation objects and existing Animation objects will all have the same
+  // start time).
+  return waitForAllAnimations(animations).then(waitForFrame).then(function() {
+    // Swap duration of first and second in list and prepend animation at the
+    // same time
+    div.style.animation = 'anim1 100s, anim1 100s, anim1 200s';
+    animations = div.getAnimations();
+    assert_true(animations[0] !== animation1 && animations[0] !== animation2,
+                'New Animation is prepended to start of list');
+    assert_equals(animations[1], animation1,
+                  'First Animation is in second position after update');
+    assert_equals(animations[2], animation2,
+                  'Second Animation is in third position after update');
+    assert_equals(animations[1].startTime, animations[2].startTime,
+                  'Old Animations have the same start time');
+    // TODO: Check that animations[0].startTime === null
+    return animations[0].ready;
+  }).then(function() {
+    assert_greater_than(animations[0].startTime, animations[1].startTime,
+                        'New Animation has later start time');
+  });
+}, 'Only the startTimes of existing animations are preserved');
+
+promise_test(function(t) {
+  var div = addDiv(t);
+  div.style.animation = 'anim1 100s, anim1 100s';
+  var secondAnimation = div.getAnimations()[1];
+
+  // Wait before continuing so we can compare start times
+  return secondAnimation.ready.then(waitForNextFrame).then(function() {
+    // Trim list of animations
+    div.style.animationName = 'anim1';
+    var animations = div.getAnimations();
+    assert_equals(animations.length, 1, 'List of Animations was trimmed');
+    assert_equals(animations[0], secondAnimation,
+                  'Remaining Animation is the second one in the list');
+    assert_equals(typeof(animations[0].startTime), 'number',
+                  'Remaining Animation has resolved startTime');
+    assert_less_than(animations[0].startTime,
+                     animations[0].timeline.currentTime,
+                     'Remaining Animation preserves startTime');
+  });
+}, 'Animations are removed from the start of the list while preserving'
+   + ' the state of existing Animations');
+
+promise_test(function(t) {
+  var div = addDiv(t);
+  div.style.animation = 'anim1 100s';
+  var firstAddedAnimation = div.getAnimations()[0],
+      secondAddedAnimation,
+      animations;
+
+  // Wait and add second Animation
+  return firstAddedAnimation.ready.then(waitForFrame).then(function() {
+    div.style.animation = 'anim1 100s, anim1 100s';
+    secondAddedAnimation = div.getAnimations()[0];
+
+    // Wait again and add another Animation
+    return secondAddedAnimation.ready.then(waitForFrame);
+  }).then(function() {
+    div.style.animation = 'anim1 100s, anim2 100s, anim1 100s';
+    animations = div.getAnimations();
+    assert_not_equals(firstAddedAnimation, secondAddedAnimation,
+                      'New Animations are added to start of the list');
+    assert_equals(animations[0], secondAddedAnimation,
+                  'Second Animation remains in same position after'
+                  + ' interleaving');
+    assert_equals(animations[2], firstAddedAnimation,
+                  'First Animation remains in same position after'
+                  + ' interleaving');
+    return animations[1].ready;
+  }).then(function() {
+    assert_greater_than(animations[1].startTime, animations[0].startTime,
+                        'Interleaved animation starts later than existing ' +
+                        'animations');
+    assert_greater_than(animations[0].startTime, animations[2].startTime,
+                        'Original animations retain their start time');
+  });
+}, 'Animation state is preserved when interleaving animations in list');
+
+</script>
+</body>
@@ -1,36 +1,34 @@
 <!doctype html>
 <meta charset=utf-8>
-<title>CSSAnimation.animationName</title>
-<link rel="help"
-      href="https://drafts.csswg.org/css-animations-2/#dom-cssanimation-animationname">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="support/testcommon.js"></script>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="../resources/testcommon.js"></script>
 <style>
 @keyframes xyz {
   to { left: 100px }
 }
 </style>
+<body>
 <div id="log"></div>
 <script>
 'use strict';
 
-test(t => {
-  const div = addDiv(t);
+test(function(t) {
+  var div = addDiv(t);
   div.style.animation = 'xyz 100s';
   assert_equals(div.getAnimations()[0].animationName, 'xyz',
                 'Animation name matches keyframes rule name');
 }, 'Animation name makes keyframe rule');
 
-test(t => {
-  const div = addDiv(t);
+test(function(t) {
+  var div = addDiv(t);
   div.style.animation = 'x\\yz 100s';
   assert_equals(div.getAnimations()[0].animationName, 'xyz',
                 'Escaped animation name matches keyframes rule name');
 }, 'Escaped animation name');
 
-test(t => {
-  const div = addDiv(t);
+test(function(t) {
+  var div = addDiv(t);
   div.style.animation = 'x\\79 z 100s';
   assert_equals(div.getAnimations()[0].animationName, 'xyz',
                 'Hex-escaped animation name matches keyframes rule'
@@ -38,3 +36,4 @@ test(t => {
 }, 'Animation name with hex-escape');
 
 </script>
+</body>
@@ -10,7 +10,7 @@ PASS Order of CSS Animations and CSS Transitions
 PASS Finished but filling CSS Animations are returned 
 PASS Finished but not filling CSS Animations are not returned 
 PASS Yet-to-start CSS Animations are returned 
-PASS CSS Animations canceled via the API are not returned 
-PASS CSS Animations canceled and restarted via the API are returned 
-FAIL CSS Animations targetting (pseudo-)elements should have correct order after sorting assert_equals: Animation #2 has expected target expected (object) Element node <div id="parent" style="animation: animBottom 100s"><div ... but got (undefined) undefined
+PASS CSS Animations cancelled via the API are not returned 
+PASS CSS Animations cancelled and restarted via the API are returned 
+PASS CSS Animations targetting (pseudo-)elements should have correct order after sorting 
 
@@ -1,10 +1,8 @@
 <!doctype html>
 <meta charset=utf-8>
-<title>Document.getAnimations() for CSS animations</title>
-<link rel="help" href="https://drafts.csswg.org/css-animations-2/#animation-composite-order">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="support/testcommon.js"></script>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="../resources/testcommon.js"></script>
 <style>
 @keyframes animLeft {
   to { left: 100px }
 @keyframes animRight {
   to { right: 100px }
 }
+::before {
+  content: ''
+}
+::after {
+  content: ''
+}
 </style>
+<body>
 <div id="log"></div>
 <script>
 'use strict';
 
-test(t => {
+test(function(t) {
   assert_equals(document.getAnimations().length, 0,
     'getAnimations returns an empty sequence for a document'
     + ' with no animations');
 }, 'getAnimations for non-animated content');
 
-test(t => {
-  const div = addDiv(t);
+test(function(t) {
+  var div = addDiv(t);
 
   // Add an animation
   div.style.animation = 'animLeft 100s';
@@ -48,12 +53,12 @@ test(t => {
                 'getAnimations returns no running CSS Animations');
 }, 'getAnimations for CSS Animations');
 
-test(t => {
-  const div = addDiv(t);
+test(function(t) {
+  var div = addDiv(t);
   div.style.animation = 'animLeft 100s, animTop 100s, animRight 100s, ' +
                         'animBottom 100s';
 
-  const animations = document.getAnimations();
+  var animations = document.getAnimations();
   assert_equals(animations.length, 4,
                 'getAnimations returns all running CSS Animations');
   assert_equals(animations[0].animationName, 'animLeft',
@@ -66,13 +71,13 @@ test(t => {
                 'Order of fourth animation returned');
 }, 'Order of CSS Animations - within an element');
 
-test(t => {
-  const div1 = addDiv(t, { style: 'animation: animLeft 100s' });
-  const div2 = addDiv(t, { style: 'animation: animLeft 100s' });
-  const div3 = addDiv(t, { style: 'animation: animLeft 100s' });
-  const div4 = addDiv(t, { style: 'animation: animLeft 100s' });
+test(function(t) {
+  var div1 = addDiv(t, { style: 'animation: animLeft 100s' });
+  var div2 = addDiv(t, { style: 'animation: animLeft 100s' });
+  var div3 = addDiv(t, { style: 'animation: animLeft 100s' });
+  var div4 = addDiv(t, { style: 'animation: animLeft 100s' });
 
-  let animations = document.getAnimations();
+  var animations = document.getAnimations();
   assert_equals(animations.length, 4,
                 'getAnimations returns all running CSS Animations');
   assert_equals(animations[0].effect.target, div1,
@@ -107,17 +112,17 @@ test(t => {
 
 }, 'Order of CSS Animations - across elements');
 
-test(t => {
-  const div1 = addDiv(t, { style: 'animation: animLeft 100s, animTop 100s' });
-  const div2 = addDiv(t, { style: 'animation: animBottom 100s' });
+test(function(t) {
+  var div1 = addDiv(t, { style: 'animation: animLeft 100s, animTop 100s' });
+  var div2 = addDiv(t, { style: 'animation: animBottom 100s' });
 
-  let expectedResults = [ [ div1, 'animLeft' ],
-                            [ div1, 'animTop' ],
-                            [ div2, 'animBottom' ] ];
-  let animations = document.getAnimations();
+  var expectedResults = [ [ div1, 'animLeft' ],
+                          [ div1, 'animTop' ],
+                          [ div2, 'animBottom' ] ];
+  var animations = document.getAnimations();
   assert_equals(animations.length, expectedResults.length,
                 'getAnimations returns all running CSS Animations');
-  animations.forEach((anim, i) => {
+  animations.forEach(function(anim, i) {
     assert_equals(anim.effect.target, expectedResults[i][0],
                   'Target of animation in position ' + i);
     assert_equals(anim.animationName, expectedResults[i][1],
@@ -136,7 +141,7 @@ test(t => {
   assert_equals(animations.length, expectedResults.length,
                 'getAnimations returns all running CSS Animations after ' +
                 'making changes');
-  animations.forEach((anim, i) => {
+  animations.forEach(function(anim, i) {
     assert_equals(anim.effect.target, expectedResults[i][0],
                   'Target of animation in position ' + i + ' after changes');
     assert_equals(anim.animationName, expectedResults[i][1],
@@ -144,9 +149,9 @@ test(t => {
   });
 }, 'Order of CSS Animations - across and within elements');
 
-test(t => {
-  const div = addDiv(t, { style: 'animation: animLeft 100s, animTop 100s' });
-  const animLeft = document.getAnimations()[0];
+test(function(t) {
+  var div = addDiv(t, { style: 'animation: animLeft 100s, animTop 100s' });
+  var animLeft = document.getAnimations()[0];
   assert_equals(animLeft.animationName, 'animLeft',
                 'Originally, animLeft animation comes first');
 
@@ -154,7 +159,7 @@ test(t => {
   div.style.animation = 'animTop 100s';
   animLeft.play();
 
-  const animations = document.getAnimations();
+  var animations = document.getAnimations();
   assert_equals(animations.length, 2,
                 'getAnimations returns markup-bound and free animations');
   assert_equals(animations[0].animationName, 'animTop',
@@ -162,17 +167,17 @@ test(t => {
   assert_equals(animations[1], animLeft, 'Free animations come last');
 }, 'Order of CSS Animations - markup-bound vs free animations');
 
-test(t => {
-  const div = addDiv(t, { style: 'animation: animLeft 100s, animTop 100s' });
-  const animLeft = document.getAnimations()[0];
-  const animTop  = document.getAnimations()[1];
+test(function(t) {
+  var div = addDiv(t, { style: 'animation: animLeft 100s, animTop 100s' });
+  var animLeft = document.getAnimations()[0];
+  var animTop  = document.getAnimations()[1];
 
   // Disassociate both animations from markup and restart in opposite order
   div.style.animation = '';
   animTop.play();
   animLeft.play();
 
-  const animations = document.getAnimations();
+  var animations = document.getAnimations();
   assert_equals(animations.length, 2,
                 'getAnimations returns free animations');
   assert_equals(animations[0], animTop,
@@ -188,9 +193,9 @@ test(t => {
                 ' does not change');
 }, 'Order of CSS Animations - free animations');
 
-test(t => {
+test(function(t) {
   // Add an animation first
-  const div = addDiv(t, { style: 'animation: animLeft 100s' });
+  var div = addDiv(t, { style: 'animation: animLeft 100s' });
   div.style.top = '0px';
   div.style.transition = 'all 100s';
   flushComputedStyle(div);
@@ -200,122 +205,80 @@ test(t => {
   flushComputedStyle(div);
 
   // Although the transition was added later, it should come first in the list
-  const animations = document.getAnimations();
+  var animations = document.getAnimations();
   assert_equals(animations.length, 2,
                 'Both CSS animations and transitions are returned');
   assert_class_string(animations[0], 'CSSTransition', 'Transition comes first');
   assert_class_string(animations[1], 'CSSAnimation', 'Animation comes second');
 }, 'Order of CSS Animations and CSS Transitions');
 
-test(t => {
-  const div = addDiv(t, { style: 'animation: animLeft 100s forwards' });
+test(function(t) {
+  var div = addDiv(t, { style: 'animation: animLeft 100s forwards' });
   div.getAnimations()[0].finish();
   assert_equals(document.getAnimations().length, 1,
                 'Forwards-filling CSS animations are returned');
 }, 'Finished but filling CSS Animations are returned');
 
-test(t => {
-  const div = addDiv(t, { style: 'animation: animLeft 100s' });
+test(function(t) {
+  var div = addDiv(t, { style: 'animation: animLeft 100s' });
   div.getAnimations()[0].finish();
   assert_equals(document.getAnimations().length, 0,
                 'Non-filling finished CSS animations are not returned');
 }, 'Finished but not filling CSS Animations are not returned');
 
-test(t => {
-  const div = addDiv(t, { style: 'animation: animLeft 100s 100s' });
+test(function(t) {
+  var div = addDiv(t, { style: 'animation: animLeft 100s 100s' });
   assert_equals(document.getAnimations().length, 1,
                 'Yet-to-start CSS animations are returned');
 }, 'Yet-to-start CSS Animations are returned');
 
-test(t => {
-  const div = addDiv(t, { style: 'animation: animLeft 100s' });
+test(function(t) {
+  var div = addDiv(t, { style: 'animation: animLeft 100s' });
   div.getAnimations()[0].cancel();
   assert_equals(document.getAnimations().length, 0,
-                'CSS animations canceled by the API are not returned');
-}, 'CSS Animations canceled via the API are not returned');
+                'CSS animations cancelled by the API are not returned');
+}, 'CSS Animations cancelled via the API are not returned');
 
-test(t => {
-  const div = addDiv(t, { style: 'animation: animLeft 100s' });
-  const anim = div.getAnimations()[0];
+test(function(t) {
+  var div = addDiv(t, { style: 'animation: animLeft 100s' });
+  var anim = div.getAnimations()[0];
   anim.cancel();
   anim.play();
   assert_equals(document.getAnimations().length, 1,
-                'CSS animations canceled and restarted by the API are ' +
+                'CSS animations cancelled and restarted by the API are ' +
                 'returned');
-}, 'CSS Animations canceled and restarted via the API are returned');
+}, 'CSS Animations cancelled and restarted via the API are returned');
 
-test(t => {
-  // Create two divs with the following arrangement:
-  //
+test(function(t) {
+  addStyle(t, { '#parent::after': 'animation: animLeft 10s;',
+                '#parent::before': 'animation: animRight 10s;' });
+  // create two divs with these arrangement:
   //       parent
-  //    (::marker,)
   //     ::before,
   //     ::after
   //        |
   //       child
-
-  addStyle(t, {
-    '#parent::after': "content: ''; animation: animLeft 100s;",
-    '#parent::before': "content: ''; animation: animRight 100s;",
+  var parent = addDiv(t, { 'id': 'parent' });
+  var child = addDiv(t, { 'id': 'child' });
+  parent.appendChild(child);
+  [parent, child].forEach((div) => {
+    div.setAttribute('style', 'animation: animBottom 10s');
   });
 
-  const supportsMarkerPseudos = CSS.supports('selector(::marker)');
-  if (supportsMarkerPseudos) {
-    addStyle(t, {
-      '#parent': 'display: list-item;',
-      '#parent::marker': "content: ''; animation: animLeft 100s;",
-    });
-  }
-
-  const parent = addDiv(t, { id: 'parent' });
-  const child = addDiv(t);
-  parent.appendChild(child);
-  for (const div of [parent, child]) {
-    div.setAttribute('style', 'animation: animBottom 100s');
-  }
-
-  const expectedAnimations = [
-    [parent, undefined],
-    [parent, '::marker'],
-    [parent, '::before'],
-    [parent, '::after'],
-    [child, undefined],
-  ];
-  if (!supportsMarkerPseudos) {
-    expectedAnimations.splice(1, 1);
-  }
-
-  const animations = document.getAnimations();
-  assert_equals(
-    animations.length,
-    expectedAnimations.length,
-    'CSS animations on both pseudo-elements and elements are returned'
-  );
-
-  for (const [index, expected] of expectedAnimations.entries()) {
-    const [element, pseudo] = expected;
-    const actual = animations[index];
-
-    if (pseudo) {
-      assert_equals(
-        actual.effect.target.element,
-        element,
-        `Animation #${index + 1} has expected target`
-      );
-      assert_equals(
-        actual.effect.target.type,
-        pseudo,
-        `Animation #${index + 1} has expected pseudo type`
-      );
-    } else {
-      assert_equals(
-        actual.effect.target,
-        element,
-        `Animation #${index + 1} has expected target`
-      );
-    }
-  }
-}, 'CSS Animations targetting (pseudo-)elements should have correct order '
-   + 'after sorting');
+  var anims = document.getAnimations();
+  assert_equals(anims.length, 4,
+                'CSS animations on both pseudo-elements and elements ' +
+                'are returned');
+  assert_equals(anims[0].effect.target, parent,
+                'The animation targeting the parent element comes first');
+  assert_equals(anims[1].animationName, 'animRight',
+                'The animation targeting the ::before element comes second');
+  assert_equals(anims[2].animationName, 'animLeft',
+                'The animation targeting the ::after element comes third');
+  assert_equals(anims[3].effect.target, child,
+                'The animation targeting the child element comes last');
+}, 'CSS Animations targetting (pseudo-)elements should have correct order ' +
+   'after sorting');
 
 </script>
+</body>
@@ -1,11 +1,8 @@
 <!doctype html>
 <meta charset=utf-8>
-<title>CSSAnimation.effect.target</title>
-<!--  TODO: Add a more specific link for this once it is specified.  -->
-<link rel="help" href="https://drafts.csswg.org/css-animations-2/">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="support/testcommon.js"></script>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="../resources/testcommon.js"></script>
 <style>
 @keyframes anim { }
 ::before {
   content: ''
 }
 </style>
+<body>
 <div id="log"></div>
 <script>
 'use strict';
 
-test(t => {
-  const div = addDiv(t);
+test(function(t) {
+  var div = addDiv(t);
   div.style.animation = 'anim 100s';
-  const animation = div.getAnimations()[0];
+  var animation = div.getAnimations()[0];
   assert_equals(animation.effect.target, div,
     'Animation.target is the animatable div');
 }, 'Returned CSS animations have the correct effect target');
 
-test(t => {
+test(function(t) {
   addStyle(t, { '.after::after': 'animation: anim 10s, anim 100s;' });
-  const div = addDiv(t, { class: 'after' });
-  const anims = document.getAnimations();
+  var div = addDiv(t, { class: 'after' });
+  var anims = document.getAnimations();
   assert_equals(anims.length, 2,
                 'Got animations running on ::after pseudo element');
   assert_equals(anims[0].effect.target, anims[1].effect.target,
                 'Both animations return the same target object');
 }, 'effect.target should return the same CSSPseudoElement object each time');
 
-test(t => {
+test(function(t) {
   addStyle(t, { '.after::after': 'animation: anim 10s;' });
-  const div = addDiv(t, { class: 'after' });
-  const pseudoTarget = document.getAnimations()[0].effect.target;
-  const effect = new KeyframeEffect(pseudoTarget,
-                                    { background: ["blue", "red"] },
-                                    3 * MS_PER_SEC);
-  const newAnim = new Animation(effect, document.timeline);
+  var div = addDiv(t, { class: 'after' });
+  var pseudoTarget = document.getAnimations()[0].effect.target;
+  var effect = new KeyframeEffect(pseudoTarget,
+                                          { background: ["blue", "red"] },
+                                          3 * MS_PER_SEC);
+  var newAnim = new Animation(effect, document.timeline);
   newAnim.play();
-  const anims = document.getAnimations();
+  var anims = document.getAnimations();
   assert_equals(anims.length, 2,
                 'Got animations running on ::after pseudo element');
   assert_not_equals(anims[0], newAnim,
@@ -61,3 +59,4 @@ test(t => {
    'CSSPseudoElement object as that from the CSS generated animation');
 
 </script>
+</body>
@@ -14,11 +14,11 @@ PASS getAnimations for CSS Animations with empty keyframes rule
 PASS getAnimations for CSS animations in delay phase 
 PASS getAnimations for zero-duration CSS Animations 
 PASS getAnimations returns objects with the same identity 
-PASS getAnimations for CSS Animations that are canceled 
+PASS getAnimations for CSS Animations that are cancelled 
 FAIL getAnimations for CSS Animations follows animation-name order assert_equals: animation order after prepending to list expected "anim1" but got "anim2"
-PASS { subtree: false } on a leaf element returns the element's animations and ignore pseudo-elements 
-FAIL { subtree: true } on a leaf element returns the element's animations and its pseudo-elements' animations assert_equals: getAnimations({ subtree: true }) should return animations on pseudo-elements expected 3 but got 1
-PASS { subtree: false } on an element with a child returns only the element's animations 
-FAIL { subtree: true } on an element with a child returns animations from the element, its pseudo-elements, its child and its child pseudo-elements assert_equals: Should find all elements, pesudo-elements that parent has expected 6 but got 1
-FAIL { subtree: true } on an element with many descendants returns animations from all the descendants assert_equals: Should find all descendants of the element expected 5 but got 1
+PASS Test AnimationFilter{ subtree: false } with single element 
+FAIL Test AnimationFilter{ subtree: true } with single element assert_equals: getAnimations({ subtree: true }) should return animations on pseudo-elements expected 3 but got 1
+PASS Test AnimationFilter{ subtree: false } with element that has a child 
+FAIL Test AnimationFilter{ subtree: true } with element that has a child assert_equals: Should find all elements, pesudo-elements that parent has expected 6 but got 1
+FAIL Test AnimationFilter{ subtree: true } with element that has many descendant assert_equals: Should find all descendants of the element expected 5 but got 1
 
@@ -1,11 +1,8 @@
 <!doctype html>
 <meta charset=utf-8>
-<title>Element.getAnimations() for CSS animations</title>
-<!--  TODO: Add a more specific link for this once it is specified.  -->
-<link rel="help" href="https://drafts.csswg.org/css-animations-2/">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="support/testcommon.js"></script>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="../resources/testcommon.js"></script>
 <style>
 @keyframes anim1 {
   to { left: 100px }
 }
 @keyframes empty { }
 </style>
+<body>
 <div id="log"></div>
 <script>
 'use strict';
 
-test(t => {
-  const div = addDiv(t);
+test(function(t) {
+  var div = addDiv(t);
   assert_equals(div.getAnimations().length, 0,
     'getAnimations returns an empty sequence for an element'
     + ' with no animations');
 }, 'getAnimations for non-animated content');
 
-promise_test(async t => {
-  const div = addDiv(t);
+promise_test(function(t) {
+  var div = addDiv(t);
+
+  // FIXME: This test does too many things. It should be split up.
 
   // Add an animation
   div.style.animation = 'anim1 100s';
-  let animations = div.getAnimations();
+  var animations = div.getAnimations();
   assert_equals(animations.length, 1,
     'getAnimations returns an Animation running CSS Animations');
-  await animations[0].ready;
-
-  // Add a second animation
-  div.style.animation = 'anim1 100s, anim2 100s';
-  animations = div.getAnimations();
-  assert_equals(animations.length, 2,
-    'getAnimations returns one CSSAnimation for each value of animation-name');
-  // (We don't check the order of the Animations since that is covered by tests
-  //  later in this file.)
+  return animations[0].ready.then(function() {
+    var startTime = animations[0].startTime;
+    assert_true(startTime > 0 && startTime <= document.timeline.currentTime,
+      'CSS animation has a sensible start time');
+
+    // Wait a moment then add a second animation.
+    //
+    // We wait for the next frame so that we can test that the start times of
+    // the animations differ.
+    return waitForFrame();
+  }).then(function() {
+    div.style.animation = 'anim1 100s, anim2 100s';
+    animations = div.getAnimations();
+    assert_equals(animations.length, 2,
+      'getAnimations returns one Animation for each value of'
+      + ' animation-name');
+    // Wait until both Animations are ready
+    // (We don't make any assumptions about the order of the Animations since
+    //  that is the purpose of the following test.)
+    return waitForAllAnimations(animations);
+  }).then(function() {
+    assert_true(animations[0].startTime < animations[1].startTime,
+      'Additional Animations for CSS animations start after the original'
+      + ' animation and appear later in the list');
+  });
 }, 'getAnimations for CSS Animations');
 
-test(t => {
-  const div = addDiv(t, { style: 'animation: anim1 100s' });
+test(function(t) {
+  var div = addDiv(t, { style: 'animation: anim1 100s' });
   assert_class_string(div.getAnimations()[0], 'CSSAnimation',
                       'Interface of returned animation is CSSAnimation');
 }, 'getAnimations returns CSSAnimation objects for CSS Animations');
 
-test(t => {
-  const div = addDiv(t);
+test(function(t) {
+  var div = addDiv(t);
 
   // Add an animation that targets multiple properties
   div.style.animation = 'multiPropAnim 100s';
@@ -70,8 +86,8 @@ test(t => {
     + ' that targets multiple properties');
 }, 'getAnimations for multi-property animations');
 
-promise_test(async t => {
-  const div = addDiv(t);
+promise_test(function(t) {
+  var div = addDiv(t);
 
   // Add an animation
   div.style.backgroundColor = 'red';
@@ -79,28 +95,27 @@ promise_test(async t => {
   getComputedStyle(div).backgroundColor;
 
   // Wait until a frame after the animation starts, then add a transition
-  let animations = div.getAnimations();
-  await animations[0].ready;
-  await waitForFrame();
-
-  div.style.transition = 'all 100s';
-  div.style.backgroundColor = 'green';
-
-  animations = div.getAnimations();
-  assert_equals(animations.length, 2,
-    'getAnimations returns Animations for both animations and'
-    + ' transitions that run simultaneously');
-  assert_class_string(animations[0], 'CSSTransition',
-                      'First-returned animation is the CSS Transition');
-  assert_class_string(animations[1], 'CSSAnimation',
-                      'Second-returned animation is the CSS Animation');
+  var animations = div.getAnimations();
+  return animations[0].ready.then(waitForFrame).then(function() {
+    div.style.transition = 'all 100s';
+    div.style.backgroundColor = 'green';
+
+    animations = div.getAnimations();
+    assert_equals(animations.length, 2,
+      'getAnimations returns Animations for both animations and'
+      + ' transitions that run simultaneously');
+    assert_class_string(animations[0], 'CSSTransition',
+                        'First-returned animation is the CSS Transition');
+    assert_class_string(animations[1], 'CSSAnimation',
+                        'Second-returned animation is the CSS Animation');
+  });
 }, 'getAnimations for both CSS Animations and CSS Transitions at once');
 
-async_test(t => {
-  const div = addDiv(t);
+async_test(function(t) {
+  var div = addDiv(t);
 
   // Set up event listener
-  div.addEventListener('animationend', t.step_func(() => {
+  div.addEventListener('animationend', t.step_func(function() {
     assert_equals(div.getAnimations().length, 0,
       'getAnimations does not return Animations for finished '
       + ' (and non-forwards-filling) CSS Animations');
@@ -111,11 +126,11 @@ async_test(t => {
   div.style.animation = 'anim1 0.01s';
 }, 'getAnimations for CSS Animations that have finished');
 
-async_test(t => {
-  const div = addDiv(t);
+async_test(function(t) {
+  var div = addDiv(t);
 
   // Set up event listener
-  div.addEventListener('animationend', t.step_func(() => {
+  div.addEventListener('animationend', t.step_func(function() {
     assert_equals(div.getAnimations().length, 1,
       'getAnimations returns Animations for CSS Animations that have'
       + ' finished but are filling forwards');
@@ -127,11 +142,11 @@ async_test(t => {
 }, 'getAnimations for CSS Animations that have finished but are'
    + ' forwards filling');
 
-test(t => {
-  const div = addDiv(t);
+test(function(t) {
+  var div = addDiv(t);
   div.style.animation = 'none 100s';
 
-  let animations = div.getAnimations();
+  var animations = div.getAnimations();
   assert_equals(animations.length, 0,
     'getAnimations returns an empty sequence for an element'
     + ' with animation-name: none');
@@ -143,10 +158,10 @@ test(t => {
     + ' animation-name is not none');
 }, 'getAnimations for CSS Animations with animation-name: none');
 
-test(t => {
-  const div = addDiv(t);
+test(function(t) {
+  var div = addDiv(t);
   div.style.animation = 'missing 100s';
-  let animations = div.getAnimations();
+  var animations = div.getAnimations();
   assert_equals(animations.length, 0,
     'getAnimations returns an empty sequence for an element'
     + ' with animation-name: missing');
@@ -158,64 +173,62 @@ test(t => {
     + ' animation-name is found');
 }, 'getAnimations for CSS Animations with animation-name: missing');
 
-promise_test(async t => {
-  const div = addDiv(t);
+promise_test(function(t) {
+  var div = addDiv(t);
   div.style.animation = 'anim1 100s, notyet 100s';
-  let animations = div.getAnimations();
+  var animations = div.getAnimations();
   assert_equals(animations.length, 1,
     'getAnimations initally only returns Animations for CSS Animations whose'
     + ' animation-name is found');
 
-  await animations[0].ready;
-  await waitForFrame();
-
-  const keyframes = '@keyframes notyet { to { left: 100px; } }';
-  document.styleSheets[0].insertRule(keyframes, 0);
-  animations = div.getAnimations();
-  assert_equals(animations.length, 2,
-    'getAnimations includes Animation when @keyframes rule is added'
-    + ' later');
-  await waitForAllAnimations(animations);
-
-  assert_true(animations[0].startTime < animations[1].startTime,
-    'Newly added animation has a later start time');
-  document.styleSheets[0].deleteRule(0);
+  return animations[0].ready.then(waitForFrame).then(function() {
+    var keyframes = '@keyframes notyet { to { left: 100px; } }';
+    document.styleSheets[0].insertRule(keyframes, 0);
+    animations = div.getAnimations();
+    assert_equals(animations.length, 2,
+      'getAnimations includes Animation when @keyframes rule is added'
+      + ' later');
+    return waitForAllAnimations(animations);
+  }).then(function() {
+    assert_true(animations[0].startTime < animations[1].startTime,
+      'Newly added animation has a later start time');
+    document.styleSheets[0].deleteRule(0);
+  });
 }, 'getAnimations for CSS Animations where the @keyframes rule is added'
    + ' later');
 
-test(t => {
-  const div = addDiv(t);
+test(function(t) {
+  var div = addDiv(t);
   div.style.animation = 'anim1 100s, anim1 100s';
   assert_equals(div.getAnimations().length, 2,
     'getAnimations returns one Animation for each CSS animation-name'
     + ' even if the names are duplicated');
 }, 'getAnimations for CSS Animations with duplicated animation-name');
 
-test(t => {
-  const div = addDiv(t);
+test(function(t) {
+  var div = addDiv(t);
   div.style.animation = 'empty 100s';
   assert_equals(div.getAnimations().length, 1,
     'getAnimations returns Animations for CSS animations with an'
     + ' empty keyframes rule');
 }, 'getAnimations for CSS Animations with empty keyframes rule');
 
-promise_test(async t => {
-  const div = addDiv(t);
+promise_test(function(t) {
+  var div = addDiv(t);
   div.style.animation = 'anim1 100s 100s';
-  const animations = div.getAnimations();
+  var animations = div.getAnimations();
   assert_equals(animations.length, 1,
     'getAnimations returns animations for CSS animations whose'
     + ' delay makes them start later');
-  await animations[0].ready;
-  await waitForFrame();
-
-  assert_true(animations[0].startTime <= document.timeline.currentTime,
-    'For CSS Animations in delay phase, the start time of the Animation is'
-    + ' not in the future');
+  return animations[0].ready.then(waitForFrame).then(function() {
+    assert_true(animations[0].startTime <= document.timeline.currentTime,
+      'For CSS Animations in delay phase, the start time of the Animation is'
+      + ' not in the future');
+  });
 }, 'getAnimations for CSS animations in delay phase');
 
-test(t => {
-  const div = addDiv(t);
+test(function(t) {
+  var div = addDiv(t);
   div.style.animation = 'anim1 0s 100s';
   assert_equals(div.getAnimations().length, 1,
     'getAnimations returns animations for CSS animations whose'
@@ -223,14 +236,14 @@ test(t => {
   div.remove();
 }, 'getAnimations for zero-duration CSS Animations');
 
-test(t => {
-  const div = addDiv(t);
+test(function(t) {
+  var div = addDiv(t);
   div.style.animation = 'anim1 100s';
-  const originalAnimation = div.getAnimations()[0];
+  var originalAnimation = div.getAnimations()[0];
 
   // Update pause state (an Animation change)
   div.style.animationPlayState = 'paused';
-  const pendingAnimation = div.getAnimations()[0];
+  var pendingAnimation = div.getAnimations()[0];
   assert_equals(pendingAnimation.playState, 'paused',
                 'animation\'s play state is updated');
   assert_equals(originalAnimation, pendingAnimation,
@@ -239,86 +252,82 @@ test(t => {
 
   // Update duration (an Animation change)
   div.style.animationDuration = '200s';
-  const extendedAnimation = div.getAnimations()[0];
-  assert_equals(
-    extendedAnimation.effect.getTiming().duration,
-    200 * MS_PER_SEC,
-    'animation\'s duration has been updated'
-  );
+  var extendedAnimation = div.getAnimations()[0];
+  // FIXME: Check extendedAnimation.effect.timing.duration has changed once the
+  // API is available
   assert_equals(originalAnimation, extendedAnimation,
                 'getAnimations returns the same objects even when their'
                 + ' duration changes');
 }, 'getAnimations returns objects with the same identity');
 
-test(t => {
-  const div = addDiv(t);
+test(function(t) {
+  var div = addDiv(t);
   div.style.animation = 'anim1 100s';
 
   assert_equals(div.getAnimations().length, 1,
-    'getAnimations returns an animation before canceling');
+    'getAnimations returns an animation before cancelling');
 
-  const animation = div.getAnimations()[0];
+  var animation = div.getAnimations()[0];
 
   animation.cancel();
   assert_equals(div.getAnimations().length, 0,
-    'getAnimations does not return canceled animations');
+    'getAnimations does not return cancelled animations');
 
   animation.play();
   assert_equals(div.getAnimations().length, 1,
-    'getAnimations returns canceled animations that have been re-started');
+    'getAnimations returns cancelled animations that have been re-started');
 
-}, 'getAnimations for CSS Animations that are canceled');
+}, 'getAnimations for CSS Animations that are cancelled');
 
-promise_test(async t => {
-  const div = addDiv(t);
+promise_test(function(t) {
+  var div = addDiv(t);
   div.style.animation = 'anim2 100s';
 
-  await div.getAnimations()[0].ready;
-
-  // Prepend to the list and test that even though anim1 was triggered
-  // *after* anim2, it should come first because it appears first
-  // in the animation-name property.
-  div.style.animation = 'anim1 100s, anim2 100s';
-  let anims = div.getAnimations();
-  assert_equals(anims[0].animationName, 'anim1',
-                'animation order after prepending to list');
-  assert_equals(anims[1].animationName, 'anim2',
-                'animation order after prepending to list');
-
-  // Normally calling cancel and play would this push anim1 to the top of
-  // the stack but it shouldn't for CSS animations that map an the
-  // animation-name property.
-  const anim1 = anims[0];
-  anim1.cancel();
-  anim1.play();
-  anims = div.getAnimations();
-  assert_equals(anims[0].animationName, 'anim1',
-                'animation order after canceling and restarting');
-  assert_equals(anims[1].animationName, 'anim2',
-                'animation order after canceling and restarting');
+  return div.getAnimations()[0].ready.then(function() {
+    // Prepend to the list and test that even though anim1 was triggered
+    // *after* anim2, it should come first because it appears first
+    // in the animation-name property.
+    div.style.animation = 'anim1 100s, anim2 100s';
+    var anims = div.getAnimations();
+    assert_equals(anims[0].animationName, 'anim1',
+                  'animation order after prepending to list');
+    assert_equals(anims[1].animationName, 'anim2',
+                  'animation order after prepending to list');
+
+    // Normally calling cancel and play would this push anim1 to the top of
+    // the stack but it shouldn't for CSS animations that map an the
+    // animation-name property.
+    var anim1 = anims[0];
+    anim1.cancel();
+    anim1.play();
+    anims = div.getAnimations();
+    assert_equals(anims[0].animationName, 'anim1',
+                  'animation order after cancelling and restarting');
+    assert_equals(anims[1].animationName, 'anim2',
+                  'animation order after cancelling and restarting');
+  });
 }, 'getAnimations for CSS Animations follows animation-name order');
 
-test(t => {
+test(function(t) {
   addStyle(t, { '#target::after': 'animation: anim1 10s;',
                 '#target::before': 'animation: anim1 10s;' });
-  const target = addDiv(t, { 'id': 'target' });
+  var target = addDiv(t, { 'id': 'target' });
   target.style.animation = 'anim1 100s';
 
-  const animations = target.getAnimations({ subtree: false });
+  var animations = target.getAnimations({ subtree: false });
   assert_equals(animations.length, 1,
                 'Should find only the element');
   assert_equals(animations[0].effect.target, target,
                 'Effect target should be the element');
-}, '{ subtree: false } on a leaf element returns the element\'s animations'
-   + ' and ignore pseudo-elements');
+}, 'Test AnimationFilter{ subtree: false } with single element');
 
-test(t => {
+test(function(t) {
   addStyle(t, { '#target::after': 'animation: anim1 10s;',
                 '#target::before': 'animation: anim1 10s;' });
-  const target = addDiv(t, { 'id': 'target' });
+  var target = addDiv(t, { 'id': 'target' });
   target.style.animation = 'anim1 100s';
 
-  const animations = target.getAnimations({ subtree: true });
+  var animations = target.getAnimations({ subtree: true });
   assert_equals(animations.length, 3,
                 'getAnimations({ subtree: true }) ' +
                 'should return animations on pseudo-elements');
@@ -331,40 +340,38 @@ test(t => {
   assert_equals(animations[2].effect.target.type, '::after',
                 'The animation targeting the ::after pesudo-element ' +
                 'should be returned last');
-}, '{ subtree: true } on a leaf element returns the element\'s animations'
-   + ' and its pseudo-elements\' animations');
+}, 'Test AnimationFilter{ subtree: true } with single element');
 
-test(t => {
+test(function(t) {
   addStyle(t, { '#parent::after': 'animation: anim1 10s;',
                 '#parent::before': 'animation: anim1 10s;',
                 '#child::after': 'animation: anim1 10s;',
                 '#child::before': 'animation: anim1 10s;' });
-  const parent = addDiv(t, { 'id': 'parent' });
+  var parent = addDiv(t, { 'id': 'parent' });
   parent.style.animation = 'anim1 100s';
-  const child = addDiv(t, { 'id': 'child' });
+  var child = addDiv(t, { 'id': 'child' });
   child.style.animation = 'anim1 100s';
   parent.appendChild(child);
 
-  const animations = parent.getAnimations({ subtree: false });
+  var animations = parent.getAnimations({ subtree: false });
   assert_equals(animations.length, 1,
                 'Should find only the element even if it has a child');
   assert_equals(animations[0].effect.target, parent,
                 'Effect target shuld be the element');
-}, '{ subtree: false } on an element with a child returns only the element\'s'
-   + ' animations');
+}, 'Test AnimationFilter{ subtree: false } with element that has a child');
 
-test(t => {
+test(function(t) {
   addStyle(t, { '#parent::after': 'animation: anim1 10s;',
                 '#parent::before': 'animation: anim1 10s;',
                 '#child::after': 'animation: anim1 10s;',
                 '#child::before': 'animation: anim1 10s;' });
-  const parent = addDiv(t, { 'id': 'parent' });
-  const child = addDiv(t, { 'id': 'child' });
+  var parent = addDiv(t, { 'id': 'parent' });
+  var child = addDiv(t, { 'id': 'child' });
   parent.style.animation = 'anim1 100s';
   child.style.animation = 'anim1 100s';
   parent.appendChild(child);
 
-  const animations = parent.getAnimations({ subtree: true });
+  var animations = parent.getAnimations({ subtree: true });
   assert_equals(animations.length, 6,
                 'Should find all elements, pesudo-elements that parent has');
 
@@ -374,12 +381,12 @@ test(t => {
   assert_equals(animations[1].effect.target.type, '::before',
                 'The animation targeting the ::before pseudo-element ' +
                 'should be returned second');
-  assert_equals(animations[1].effect.target.element, parent,
+  assert_equals(animations[1].effect.target.parentElement, parent,
                 'This ::before element should be child of parent element');
   assert_equals(animations[2].effect.target.type, '::after',
                 'The animation targeting the ::after pesudo-element ' +
                 'should be returned third');
-  assert_equals(animations[2].effect.target.element, parent,
+  assert_equals(animations[2].effect.target.parentElement, parent,
                 'This ::after element should be child of parent element');
 
   assert_equals(animations[3].effect.target, child,
@@ -388,22 +395,21 @@ test(t => {
   assert_equals(animations[4].effect.target.type, '::before',
                 'The animation targeting the ::before pseudo-element ' +
                 'should be returned fifth');
-  assert_equals(animations[4].effect.target.element, child,
+  assert_equals(animations[4].effect.target.parentElement, child,
                 'This ::before element should be child of child element');
   assert_equals(animations[5].effect.target.type, '::after',
                 'The animation targeting the ::after pesudo-element ' +
                 'should be returned last');
-  assert_equals(animations[5].effect.target.element, child,
+  assert_equals(animations[5].effect.target.parentElement, child,
                 'This ::after element should be child of child element');
-}, '{ subtree: true } on an element with a child returns animations from the'
-   + ' element, its pseudo-elements, its child and its child pseudo-elements');
+}, 'Test AnimationFilter{ subtree: true } with element that has a child');
 
-test(t => {
-  const parent = addDiv(t, { 'id': 'parent' });
-  const child1 = addDiv(t, { 'id': 'child1' });
-  const grandchild1 = addDiv(t, { 'id': 'grandchild1' });
-  const grandchild2 = addDiv(t, { 'id': 'grandchild2' });
-  const child2 = addDiv(t, { 'id': 'child2' });
+test(function(t) {
+  var parent = addDiv(t, { 'id': 'parent' });
+  var child1 = addDiv(t, { 'id': 'child1' });
+  var grandchild1 = addDiv(t, { 'id': 'grandchild1' });
+  var grandchild2 = addDiv(t, { 'id': 'grandchild2' });
+  var child2 = addDiv(t, { 'id': 'child2' });
 
   parent.style.animation = 'anim1 100s';
   child1.style.animation = 'anim1 100s';
@@ -416,7 +422,7 @@ test(t => {
   child1.appendChild(grandchild2);
   parent.appendChild(child2);
 
-  const animations = parent.getAnimations({ subtree: true });
+  var animations = parent.getAnimations({ subtree: true });
   assert_equals(
     parent.getAnimations({ subtree: true }).length, 5,
                          'Should find all descendants of the element');
@@ -441,7 +447,7 @@ test(t => {
                 'The animation targeting the child2 element ' +
                 'should be returned last');
 
-}, '{ subtree: true } on an element with many descendants returns animations'
-   + ' from all the descendants');
+}, 'Test AnimationFilter{ subtree: true } with element that has many descendant');
 
 </script>
+</body>
@@ -14,16 +14,10 @@ PASS Active -> Active (forwards)
 PASS Active -> Active (backwards) 
 PASS Active -> Idle -> Active: animationstart is fired by restarting animation 
 PASS Negative playbackRate sanity test(Before -> Active -> Before) 
-PASS Redundant change, before -> active, then back 
-PASS Redundant change, before -> after, then back 
-PASS Redundant change, active -> before, then back 
-PASS Redundant change, active -> after, then back 
-PASS Redundant change, after -> before, then back 
-PASS Redundant change, after -> active, then back 
-PASS Call Animation.cancel after canceling animation. 
-PASS Restart animation after canceling animation immediately. 
+PASS Call Animation.cancel after cancelling animation. 
+PASS Restart animation after cancelling animation immediately. 
 PASS Call Animation.cancel after restarting animation immediately. 
 PASS Set timeline and play transition after clearing the timeline. 
-PASS Set null target effect after canceling the animation. 
+PASS Set null target effect after cancelling the animation. 
 PASS Cancel the animation after clearing the target effect. 
 
diff --git a/LayoutTests/imported/mozilla/css-animations/test_event-dispatch.html b/LayoutTests/imported/mozilla/css-animations/test_event-dispatch.html
new file mode 100644 (file)
index 0000000..9073755
--- /dev/null
@@ -0,0 +1,381 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Tests for CSS animation event dispatch</title>
+<link rel="help" href="https://drafts.csswg.org/css-animations-2/#event-dispatch"/>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="../resources/testcommon.js"></script>
+<style>
+  @keyframes anim {
+    from { margin-left: 0px; }
+    to { margin-left: 100px; }
+  }
+</style>
+<body>
+<div id="log"></div>
+<script>
+'use strict';
+
+/**
+ * Helper class to record the elapsedTime member of each event.
+ * The EventWatcher class in testharness.js allows us to wait on
+ * multiple events in a certain order but only records the event
+ * parameters of the most recent event.
+ */
+function AnimationEventHandler(target) {
+  this.target = target;
+  this.target.onanimationstart = evt => {
+   this.animationstart = evt.elapsedTime;
+  };
+  this.target.onanimationiteration = evt => {
+    this.animationiteration = evt.elapsedTime;
+  };
+  this.target.onanimationend = evt => {
+    this.animationend = evt.elapsedTime;
+  };
+  this.target.onanimationcancel = evt => {
+    this.animationcancel = evt.elapsedTime;
+  };
+}
+AnimationEventHandler.prototype.clear = () => {
+  this.animationstart     = undefined;
+  this.animationiteration = undefined;
+  this.animationend       = undefined;
+  this.animationcancel    = undefined;
+}
+
+function setupAnimation(t, animationStyle) {
+  const div = addDiv(t, { style: 'animation: ' + animationStyle });
+  // Note that this AnimationEventHandler should be created before EventWatcher
+  // to capture all events in the handler prior to the EventWatcher since
+  // testharness.js proceeds when the EventWatcher received watching events.
+  const handler = new AnimationEventHandler(div);
+  const watcher = new EventWatcher(t, div, [ 'animationstart',
+                                           'animationiteration',
+                                           'animationend',
+                                           'animationcancel' ]);
+  const animation = div.getAnimations()[0];
+
+  return { animation, watcher, div, handler };
+}
+
+promise_test(t => {
+  // Add 1ms delay to ensure that the delay is not included in the elapsedTime.
+  const { animation, watcher } = setupAnimation(t, 'anim 100s 1ms');
+
+  return watcher.wait_for('animationstart').then(evt => {
+    assert_equals(evt.elapsedTime, 0.0);
+  });
+}, 'Idle -> Active');
+
+promise_test(t => {
+  const { animation, watcher, div, handler } = setupAnimation(t, 'anim 100s');
+
+  // Seek to After phase.
+  animation.finish();
+  return watcher.wait_for([ 'animationstart',
+                            'animationend' ]).then(() => {
+    assert_equals(handler.animationstart, 0.0);
+    assert_equals(handler.animationend, 100);
+  });
+}, 'Idle -> After');
+
+promise_test(t => {
+  const { animation, watcher } =
+    setupAnimation(t, 'anim 100s 100s paused');
+
+  return animation.ready.then(() => {
+    // Seek to Active phase.
+    animation.currentTime = 100 * MS_PER_SEC;
+    return watcher.wait_for('animationstart');
+  }).then(evt => {
+    assert_equals(evt.elapsedTime, 0.0);
+  });
+}, 'Before -> Active');
+
+promise_test(t => {
+  const { animation, watcher, div, handler } =
+    setupAnimation(t, 'anim 100s 100s paused');
+
+  return animation.ready.then(() => {
+    // Seek to After phase.
+    animation.finish();
+    return watcher.wait_for([ 'animationstart', 'animationend' ]);
+  }).then(evt => {
+    assert_equals(handler.animationstart, 0.0);
+    assert_equals(handler.animationend, 100.0);
+  });
+}, 'Before -> After');
+
+promise_test(t => {
+  const { animation, watcher, div } = setupAnimation(t, 'anim 100s paused');
+
+  return watcher.wait_for('animationstart').then(evt => {
+    // Make idle
+    div.style.display = 'none';
+    return watcher.wait_for('animationcancel');
+  }).then(evt => {
+    assert_equals(evt.elapsedTime, 0.0);
+  });
+}, 'Active -> Idle, display: none');
+
+promise_test(t => {
+  const { animation, watcher, div } = setupAnimation(t, 'anim 100s');
+
+  return watcher.wait_for('animationstart').then(evt => {
+    animation.currentTime = 100.0;
+    // Make idle
+    animation.timeline = null;
+    return watcher.wait_for('animationcancel');
+  }).then(evt => {
+    assert_time_equals_literal(evt.elapsedTime, 0.1);
+  });
+}, 'Active -> Idle, setting Animation.timeline = null');
+
+promise_test(t => {
+  // we should NOT pause animation since calling cancel synchronously.
+  const { animation, watcher, div } = setupAnimation(t, 'anim 100s');
+
+  return watcher.wait_for('animationstart').then(evt => {
+    animation.currentTime = 50.0;
+    animation.cancel();
+    return watcher.wait_for('animationcancel');
+  }).then(evt => {
+    assert_time_equals_literal(evt.elapsedTime, 0.05);
+  });
+}, 'Active -> Idle, calling Animation.cancel()');
+
+promise_test(t => {
+  const { animation, watcher } =
+    setupAnimation(t, 'anim 100s 100s paused');
+
+  // Seek to Active phase.
+  animation.currentTime = 100 * MS_PER_SEC;
+  return watcher.wait_for('animationstart').then(() => {
+    // Seek to Before phase.
+    animation.currentTime = 0;
+    return watcher.wait_for('animationend');
+  }).then(evt => {
+    assert_equals(evt.elapsedTime, 0.0);
+  });
+}, 'Active -> Before');
+
+promise_test(t => {
+  const { animation, watcher } = setupAnimation(t, 'anim 100s paused');
+
+  return watcher.wait_for('animationstart').then(evt => {
+    // Seek to After phase.
+    animation.finish();
+    return watcher.wait_for('animationend');
+  }).then(evt => {
+    assert_equals(evt.elapsedTime, 100.0);
+  });
+}, 'Active -> After');
+
+promise_test(t => {
+  const { animation, watcher, div, handler } =
+    setupAnimation(t, 'anim 100s 100s paused');
+
+  // Seek to After phase.
+  animation.finish();
+  return watcher.wait_for([ 'animationstart',
+                            'animationend' ]).then(() => {
+    // Seek to Before phase.
+    animation.currentTime = 0;
+    handler.clear();
+    return watcher.wait_for([ 'animationstart', 'animationend' ]);
+  }).then(() => {
+    assert_equals(handler.animationstart, 100.0);
+    assert_equals(handler.animationend, 0.0);
+  });
+}, 'After -> Before');
+
+promise_test(t => {
+  const { animation, watcher, div } =
+    setupAnimation(t, 'anim 100s 100s paused');
+
+  // Seek to After phase.
+  animation.finish();
+  return watcher.wait_for([ 'animationstart',
+                            'animationend' ]).then(() => {
+    // Seek to Active phase.
+    animation.currentTime = 100 * MS_PER_SEC;
+    return watcher.wait_for('animationstart');
+  }).then(evt => {
+    assert_equals(evt.elapsedTime, 100.0);
+  });
+}, 'After -> Active');
+
+promise_test(t => {
+  const { animation, watcher, div }
+    = setupAnimation(t, 'anim 100s 100s 3 paused');
+
+  return animation.ready.then(() => {
+    // Seek to iteration 0 (no animationiteration event should be dispatched)
+    animation.currentTime = 100 * MS_PER_SEC;
+    return watcher.wait_for('animationstart');
+  }).then(evt => {
+    // Seek to iteration 2
+    animation.currentTime = 300 * MS_PER_SEC;
+    return watcher.wait_for('animationiteration');
+  }).then(evt => {
+    assert_equals(evt.elapsedTime, 200);
+    // Seek to After phase (no animationiteration event should be dispatched)
+    animation.currentTime = 400 * MS_PER_SEC;
+    return watcher.wait_for('animationend');
+  }).then(evt => {
+    assert_equals(evt.elapsedTime, 300);
+  });
+}, 'Active -> Active (forwards)');
+
+promise_test(t => {
+  const { animation, watcher } = setupAnimation(t, 'anim 100s 100s 3');
+
+  // Seek to After phase.
+  animation.finish();
+  return watcher.wait_for([ 'animationstart',
+                            'animationend' ]).then(() => {
+    // Seek to iteration 2 (no animationiteration event should be dispatched)
+    animation.pause();
+    animation.currentTime = 300 * MS_PER_SEC;
+    return watcher.wait_for('animationstart');
+  }).then(() => {
+    // Seek to mid of iteration 0 phase.
+    animation.currentTime = 200 * MS_PER_SEC;
+    return watcher.wait_for('animationiteration');
+  }).then(evt => {
+    assert_equals(evt.elapsedTime, 200.0);
+    // Seek to before phase (no animationiteration event should be dispatched)
+    animation.currentTime = 0;
+    return watcher.wait_for('animationend');
+  });
+}, 'Active -> Active (backwards)');
+
+promise_test(t => {
+  const { animation, watcher, div } =
+    setupAnimation(t, 'anim 100s paused');
+  return watcher.wait_for('animationstart').then(evt => {
+    // Seek to Idle phase.
+    div.style.display = 'none';
+    flushComputedStyle(div);
+
+    return watcher.wait_for('animationcancel');
+  }).then(() => {
+    // Restart this animation.
+    div.style.display = '';
+    return watcher.wait_for('animationstart');
+  });
+}, 'Active -> Idle -> Active: animationstart is fired by restarting animation');
+
+promise_test(t => {
+  const { animation, watcher } =
+    setupAnimation(t, 'anim 100s 100s 2 paused');
+
+  // Make After.
+  animation.finish();
+  return watcher.wait_for([ 'animationstart',
+                            'animationend' ]).then(evt => {
+    animation.playbackRate = -1;
+    return watcher.wait_for('animationstart');
+  }).then(evt => {
+    assert_equals(evt.elapsedTime, 200);
+    // Seek to 1st iteration
+    animation.currentTime = 200 * MS_PER_SEC - 1;
+    return watcher.wait_for('animationiteration');
+  }).then(evt => {
+    assert_equals(evt.elapsedTime, 100);
+    // Seek to before
+    animation.currentTime = 100 * MS_PER_SEC - 1;
+    return watcher.wait_for('animationend');
+  }).then(evt => {
+    assert_equals(evt.elapsedTime, 0);
+    assert_equals(animation.playState, 'running'); // delay
+  });
+}, 'Negative playbackRate sanity test(Before -> Active -> Before)');
+
+promise_test(t => {
+  const { animation, watcher } = setupAnimation(t, 'anim 100s');
+
+  return watcher.wait_for('animationstart').then(evt => {
+    // Make idle
+    animation.cancel();
+    return watcher.wait_for('animationcancel');
+  }).then(evt => {
+    animation.cancel();
+    // Then wait a couple of frames and check that no event was dispatched.
+    return waitForAnimationFrames(2);
+  });
+}, 'Call Animation.cancel after cancelling animation.');
+
+promise_test(t => {
+  const { animation, watcher, div } = setupAnimation(t, 'anim 1s');
+
+  return watcher.wait_for('animationstart').then(evt => {
+    // Make idle
+
+    animation.cancel();
+    animation.play();
+    return watcher.wait_for([ 'animationcancel',
+                              'animationstart' ]);
+  });
+}, 'Restart animation after cancelling animation immediately.');
+
+promise_test(t => {
+  const { animation, watcher } = setupAnimation(t, 'anim 100s');
+
+  return watcher.wait_for('animationstart').then(evt => {
+    // Make idle
+    animation.cancel();
+    animation.play();
+    animation.cancel();
+    return watcher.wait_for('animationcancel');
+  }).then(evt => {
+    // Then wait a couple of frames and check that no event was dispatched.
+    return waitForAnimationFrames(2);
+  });
+}, 'Call Animation.cancel after restarting animation immediately.');
+
+promise_test(t => {
+  const { animation, watcher } = setupAnimation(t, 'anim 100s');
+
+  return watcher.wait_for('animationstart').then(evt => {
+    // Make idle
+    animation.timeline = null;
+    return watcher.wait_for('animationcancel');
+  }).then(evt => {
+    animation.timeline = document.timeline;
+    animation.play();
+    return watcher.wait_for('animationstart');
+  });
+}, 'Set timeline and play transition after clearing the timeline.');
+
+promise_test(t => {
+  const { animation, watcher } = setupAnimation(t, 'anim 100s');
+
+  return watcher.wait_for('animationstart').then(evt => {
+    // Make idle
+    animation.cancel();
+    return watcher.wait_for('animationcancel');
+  }).then(evt => {
+    animation.effect = null;
+    // Then wait a couple of frames and check that no event was dispatched.
+    return waitForAnimationFrames(2);
+  });
+}, 'Set null target effect after cancelling the animation.');
+
+promise_test(t => {
+  const { animation, watcher } = setupAnimation(t, 'anim 100s');
+
+  return watcher.wait_for('animationstart').then(evt => {
+    animation.effect = null;
+    return watcher.wait_for('animationend');
+  }).then(evt => {
+    animation.cancel();
+    // Then wait a couple of frames and check that no event was dispatched.
+    return waitForAnimationFrames(2);
+  });
+}, 'Cancel the animation after clearing the target effect.');
+
+</script>
+</body>
+</html>
diff --git a/LayoutTests/imported/mozilla/css-animations/test_event-order-expected.txt b/LayoutTests/imported/mozilla/css-animations/test_event-order-expected.txt
new file mode 100644 (file)
index 0000000..bfd3031
--- /dev/null
@@ -0,0 +1,6 @@
+
+PASS Test same events are ordered by elements. 
+FAIL Test start and iteration events are ordered by time. assert_equals: Event type should match expected "animationstart" but got "animationiteration"
+FAIL Test iteration and end events are ordered by time. assert_equals: Event type should match expected "animationend" but got "animationiteration"
+FAIL Test start and end events are sorted correctly when fired simultaneously assert_equals: Event target should match expected Element node <div style="animation: anim 100s 100s"></div> but got Element node <div style="animation: anim 100s 2"></div>
+
diff --git a/LayoutTests/imported/mozilla/css-animations/test_event-order.html b/LayoutTests/imported/mozilla/css-animations/test_event-order.html
new file mode 100644 (file)
index 0000000..9e65fe8
--- /dev/null
@@ -0,0 +1,163 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Tests for CSS animation event order</title>
+<link rel="help" href="https://drafts.csswg.org/css-animations-2/#event-dispatch"/>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="../resources/testcommon.js"></script>
+<style>
+  @keyframes anim {
+    from { margin-left: 0px; }
+    to { margin-left: 100px; }
+  }
+</style>
+<body>
+<div id="log"></div>
+<script type='text/javascript'>
+'use strict';
+
+/**
+ * Asserts that the set of actual and received events match.
+ * @param actualEvents   An array of the received AnimationEvent objects.
+ * @param expectedEvents A series of array objects representing the expected
+ *        events, each having the form:
+ *          [ event type, target element, elapsed time ]
+ */
+function checkEvents(actualEvents, ...expectedEvents) {
+  assert_equals(actualEvents.length, expectedEvents.length,
+                `Number of actual events (${actualEvents.length}: \
+${actualEvents.map(event => event.type).join(', ')}) should match expected \
+events (${expectedEvents.map(event => event.type).join(', ')})`);
+
+  actualEvents.forEach((actualEvent, i) => {
+    assert_equals(expectedEvents[i][0], actualEvent.type,
+                  'Event type should match');
+    assert_equals(expectedEvents[i][1], actualEvent.target,
+                  'Event target should match');
+    assert_equals(expectedEvents[i][2], actualEvent.elapsedTime,
+                  'Event\'s elapsed time should match');
+  });
+}
+
+function setupAnimation(t, animationStyle, receiveEvents) {
+  const div = addDiv(t, { style: "animation: " + animationStyle });
+
+  ['start', 'iteration', 'end'].forEach(name => {
+    div['onanimation' + name] = evt => {
+    receiveEvents.push({ type:        evt.type,
+                         target:      evt.target,
+                         elapsedTime: evt.elapsedTime });
+    };
+  });
+
+  const watcher = new EventWatcher(t, div, [ 'animationstart',
+                                             'animationiteration',
+                                             'animationend' ]);
+
+  const animation = div.getAnimations()[0];
+
+  return [animation, watcher, div];
+}
+
+promise_test(t => {
+  let events = [];
+  const [animation1, watcher1, div1] =
+    setupAnimation(t, 'anim 100s 2 paused', events);
+  const [animation2, watcher2, div2] =
+    setupAnimation(t, 'anim 100s 2 paused', events);
+
+  return Promise.all([ watcher1.wait_for('animationstart'),
+                       watcher2.wait_for('animationstart') ]).then(() => {
+    checkEvents(events, ['animationstart', div1, 0],
+                        ['animationstart', div2, 0]);
+
+    events.length = 0;  // Clear received event array
+
+    animation1.currentTime = 100 * MS_PER_SEC;
+    animation2.currentTime = 100 * MS_PER_SEC;
+    return Promise.all([ watcher1.wait_for('animationiteration'),
+                         watcher2.wait_for('animationiteration') ]);
+  }).then(() => {
+    checkEvents(events, ['animationiteration', div1, 100],
+                        ['animationiteration', div2, 100]);
+
+    events.length = 0;  // Clear received event array
+
+    animation1.finish();
+    animation2.finish();
+
+    return Promise.all([ watcher1.wait_for('animationend'),
+                         watcher2.wait_for('animationend') ]);
+  }).then(() => {
+    checkEvents(events, ['animationend', div1, 200],
+                        ['animationend', div2, 200]);
+  });
+}, 'Test same events are ordered by elements.');
+
+promise_test(t => {
+  let events = [];
+  const [animation1, watcher1, div1] =
+    setupAnimation(t, 'anim 200s 400s', events);
+  const [animation2, watcher2, div2] =
+    setupAnimation(t, 'anim 300s 2', events);
+
+  return watcher2.wait_for('animationstart').then(evt => {
+    animation1.currentTime = 400 * MS_PER_SEC;
+    animation2.currentTime = 400 * MS_PER_SEC;
+
+    events.length = 0;  // Clear received event array
+
+    return Promise.all([ watcher1.wait_for('animationstart'),
+                         watcher2.wait_for('animationiteration') ]);
+  }).then(() => {
+    checkEvents(events, ['animationiteration', div2, 300],
+                        ['animationstart',     div1, 0]);
+  });
+}, 'Test start and iteration events are ordered by time.');
+
+promise_test(t => {
+  let events = [];
+  const [animation1, watcher1, div1] =
+    setupAnimation(t, 'anim 150s', events);
+  const [animation2, watcher2, div2] =
+    setupAnimation(t, 'anim 100s 2', events);
+
+  return Promise.all([ watcher1.wait_for('animationstart'),
+                       watcher2.wait_for('animationstart') ]).then(() => {
+    animation1.currentTime = 150 * MS_PER_SEC;
+    animation2.currentTime = 150 * MS_PER_SEC;
+
+    events.length = 0;  // Clear received event array
+
+    return Promise.all([ watcher1.wait_for('animationend'),
+                         watcher2.wait_for('animationiteration') ]);
+  }).then(() => {
+    checkEvents(events, ['animationiteration', div2, 100],
+                        ['animationend',       div1, 150]);
+  });
+}, 'Test iteration and end events are ordered by time.');
+
+promise_test(t => {
+  let events = [];
+  const [animation1, watcher1, div1] =
+    setupAnimation(t, 'anim 100s 100s', events);
+  const [animation2, watcher2, div2] =
+    setupAnimation(t, 'anim 100s 2', events);
+
+  animation1.finish();
+  animation2.finish();
+
+  return Promise.all([ watcher1.wait_for([ 'animationstart',
+                                           'animationend' ]),
+                       watcher2.wait_for([ 'animationstart',
+                                           'animationend' ]) ]).then(() => {
+    checkEvents(events, ['animationstart', div2, 0],
+                        ['animationstart', div1, 0],
+                        ['animationend',   div1, 100],
+                        ['animationend',   div2, 200]);
+  });
+}, 'Test start and end events are sorted correctly when fired simultaneously');
+
+</script>
+</body>
+</html>
@@ -22,5 +22,5 @@ FAIL KeyframeEffect.getKeyframes() returns expected values for animations with b
 FAIL KeyframeEffect.getKeyframes() returns expected values for animations with CSS variables as keyframe values assert_equals: properties on ComputedKeyframe #0 expected "composite,computedOffset,easing,offset,transform" but got "composite,computedOffset,easing,offset"
 FAIL KeyframeEffect.getKeyframes() returns expected values for animations with CSS variables as keyframe values in a shorthand property assert_equals: properties on ComputedKeyframe #0 expected "composite,computedOffset,easing,marginBottom,marginLeft,marginRight,marginTop,offset" but got "composite,computedOffset,easing,offset"
 FAIL KeyframeEffect.getKeyframes() returns expected values for animations with a CSS variable which is overriden by the value in keyframe assert_equals: properties on ComputedKeyframe #0 expected "color,composite,computedOffset,easing,offset" but got "composite,computedOffset,easing,offset"
-FAIL KeyframeEffect.getKeyframes() returns expected values for animations with only custom property in a keyframe assert_equals: value for 'transform' on ComputedKeyframe #0 expected "translate(100px)" but got "none"
+FAIL KeyframeEffect.getKeyframes() returns expected values for animations with only custom property in a keyframe assert_equals: value for 'transform' on ComputedKeyframe #0 expected "translate(100px, 0px)" but got "none"
 
@@ -1,11 +1,8 @@
 <!doctype html>
 <meta charset=utf-8>
-<title>KeyframeEffect.getKeyframes() for CSS animations</title>
-<!--  TODO: Add a more specific link for this once it is specified.  -->
-<link rel="help" href="https://drafts.csswg.org/css-animations-2/">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="support/testcommon.js"></script>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="../resources/testcommon.js"></script>
 <style>
 @keyframes anim-empty { }
 
 <script>
 "use strict";
 
-const getKeyframes = elem => elem.getAnimations()[0].effect.getKeyframes();
+function getKeyframes(e) {
+  return e.getAnimations()[0].effect.getKeyframes();
+}
 
-const assert_frames_equal = (a, b, name) => {
+function assert_frames_equal(a, b, name) {
   assert_equals(Object.keys(a).sort().toString(),
                 Object.keys(b).sort().toString(),
                 "properties on " + name);
-  for (const p in a) {
+  for (var p in a) {
     if (p === 'offset' || p === 'computedOffset') {
       assert_approx_equals(a[p], b[p], 0.00001,
                            "value for '" + p + "' on " + name);
@@ -176,7 +175,7 @@ const assert_frames_equal = (a, b, name) => {
       assert_equals(a[p], b[p], "value for '" + p + "' on " + name);
     }
   }
-};
+}
 
 // animation-timing-function values to test with, where the value
 // is exactly the same as its serialization, sorted by the order
@@ -196,8 +195,8 @@ const kTimingFunctionValues = [
   "cubic-bezier(0, 0.25, 0.75, 1)"
 ];
 
-test(t => {
-  const div = addDiv(t);
+test(function(t) {
+  var div = addDiv(t);
 
   div.style.animation = 'anim-empty 100s';
   assert_equals(getKeyframes(div).length, 0,
@@ -219,50 +218,50 @@ test(t => {
 }, 'KeyframeEffect.getKeyframes() returns no frames for various kinds'
    + ' of empty enimations');
 
-test(t => {
-  const div = addDiv(t);
+test(function(t) {
+  var div = addDiv(t);
 
   div.style.animation = 'anim-simple 100s';
-  const frames = getKeyframes(div);
+  var frames = getKeyframes(div);
 
   assert_equals(frames.length, 2, "number of frames");
 
-  const expected = [
+  var expected = [
     { offset: 0, computedOffset: 0, easing: "ease",
       color: "rgb(0, 0, 0)", composite: "auto" },
     { offset: 1, computedOffset: 1, easing: "ease",
       color: "rgb(255, 255, 255)", composite: "auto" },
   ];
 
-  for (let i = 0; i < frames.length; i++) {
+  for (var i = 0; i < frames.length; i++) {
     assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
   }
 }, 'KeyframeEffect.getKeyframes() returns expected frames for a simple'
    + ' animation');
 
-test(t => {
-  for (const easing of kTimingFunctionValues) {
-    const div = addDiv(t);
+test(function(t) {
+  kTimingFunctionValues.forEach(function(easing) {
+    var div = addDiv(t);
 
     div.style.animation = 'anim-simple-three 100s ' + easing;
-    const frames = getKeyframes(div);
+    var frames = getKeyframes(div);
 
     assert_equals(frames.length, 3, "number of frames");
 
-    for (let i = 0; i < frames.length; i++) {
+    for (var i = 0; i < frames.length; i++) {
       assert_equals(frames[i].easing, easing,
                     "value for 'easing' on ComputedKeyframe #" + i);
     }
-  }
+  });
 }, 'KeyframeEffect.getKeyframes() returns frames with expected easing'
    + ' values, when the easing comes from animation-timing-function on the'
    + ' element');
 
-test(t => {
-  const div = addDiv(t);
+test(function(t) {
+  var div = addDiv(t);
 
   div.style.animation = 'anim-simple-timing 100s';
-  const frames = getKeyframes(div);
+  var frames = getKeyframes(div);
 
   assert_equals(frames.length, 3, "number of frames");
   assert_equals(frames[0].easing, "linear",
@@ -274,11 +273,11 @@ test(t => {
 }, 'KeyframeEffect.getKeyframes() returns frames with expected easing'
    + ' values, when the easing is specified on each keyframe');
 
-test(t => {
-  const div = addDiv(t);
+test(function(t) {
+  var div = addDiv(t);
 
   div.style.animation = 'anim-simple-timing-some 100s step-start';
-  const frames = getKeyframes(div);
+  var frames = getKeyframes(div);
 
   assert_equals(frames.length, 3, "number of frames");
   assert_equals(frames[0].easing, "linear",
@@ -290,15 +289,15 @@ test(t => {
 }, 'KeyframeEffect.getKeyframes() returns frames with expected easing'
    + ' values, when the easing is specified on some keyframes');
 
-test(t => {
-  const div = addDiv(t);
+test(function(t) {
+  var div = addDiv(t);
 
   div.style.animation = 'anim-simple-shorthand 100s';
-  const frames = getKeyframes(div);
+  var frames = getKeyframes(div);
 
   assert_equals(frames.length, 2, "number of frames");
 
-  const expected = [
+  var expected = [
     { offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
       marginBottom: "8px", marginLeft: "8px",
       marginRight: "8px", marginTop: "8px" },
@@ -307,66 +306,66 @@ test(t => {
       marginRight: "16px", marginTop: "16px" },
   ];
 
-  for (let i = 0; i < frames.length; i++) {
+  for (var i = 0; i < frames.length; i++) {
     assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
   }
 }, 'KeyframeEffect.getKeyframes() returns expected frames for a simple'
    + ' animation that specifies a single shorthand property');
 
-test(t => {
-  const div = addDiv(t);
+test(function(t) {
+  var div = addDiv(t);
 
   div.style.animation = 'anim-omit-to 100s';
   div.style.color = 'rgb(255, 255, 255)';
-  const frames = getKeyframes(div);
+  var frames = getKeyframes(div);
 
   assert_equals(frames.length, 2, "number of frames");
 
-  const expected = [
+  var expected = [
     { offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
       color: "rgb(0, 0, 255)" },
     { offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
       color: "rgb(255, 255, 255)" },
   ];
 
-  for (let i = 0; i < frames.length; i++) {
+  for (var i = 0; i < frames.length; i++) {
     assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
   }
 }, 'KeyframeEffect.getKeyframes() returns expected frames for an ' +
    'animation with a 0% keyframe and no 100% keyframe');
 
-test(t => {
-  const div = addDiv(t);
+test(function(t) {
+  var div = addDiv(t);
 
   div.style.animation = 'anim-omit-from 100s';
   div.style.color = 'rgb(255, 255, 255)';
-  const frames = getKeyframes(div);
+  var frames = getKeyframes(div);
 
   assert_equals(frames.length, 2, "number of frames");
 
-  const expected = [
+  var expected = [
     { offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
       color: "rgb(255, 255, 255)" },
     { offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
       color: "rgb(0, 0, 255)" },
   ];
 
-  for (let i = 0; i < frames.length; i++) {
+  for (var i = 0; i < frames.length; i++) {
     assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
   }
 }, 'KeyframeEffect.getKeyframes() returns expected frames for an ' +
    'animation with a 100% keyframe and no 0% keyframe');
 
-test(t => {
-  const div = addDiv(t);
+test(function(t) {
+  var div = addDiv(t);
 
   div.style.animation = 'anim-omit-from-to 100s';
   div.style.color = 'rgb(255, 255, 255)';
-  const frames = getKeyframes(div);
+  var frames = getKeyframes(div);
 
   assert_equals(frames.length, 3, "number of frames");
 
-  const expected = [
+  var expected = [
     { offset: 0,   computedOffset: 0,   easing: "ease", composite: "auto",
       color: "rgb(255, 255, 255)" },
     { offset: 0.5, computedOffset: 0.5, easing: "ease", composite: "auto",
@@ -375,44 +374,44 @@ test(t => {
       color: "rgb(255, 255, 255)" },
   ];
 
-  for (let i = 0; i < frames.length; i++) {
+  for (var i = 0; i < frames.length; i++) {
     assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
   }
 }, 'KeyframeEffect.getKeyframes() returns expected frames for an ' +
    'animation with no 0% or 100% keyframe but with a 50% keyframe');
 
-test(t => {
-  const div = addDiv(t);
+test(function(t) {
+  var div = addDiv(t);
 
   div.style.animation = 'anim-partially-omit-to 100s';
   div.style.marginTop = '250px';
-  const frames = getKeyframes(div);
+  var frames = getKeyframes(div);
 
   assert_equals(frames.length, 2, "number of frames");
 
-  const expected = [
+  var expected = [
     { offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
       marginTop: '50px', marginBottom: '100px' },
     { offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
       marginTop: '250px', marginBottom: '200px' },
   ];
 
-  for (let i = 0; i < frames.length; i++) {
+  for (var i = 0; i < frames.length; i++) {
     assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
   }
 }, 'KeyframeEffect.getKeyframes() returns expected frames for an ' +
    'animation with a partially complete 100% keyframe (because the ' +
    '!important rule is ignored)');
 
-test(t => {
-  const div = addDiv(t);
+test(function(t) {
+  var div = addDiv(t);
 
   div.style.animation = 'anim-different-props 100s';
-  const frames = getKeyframes(div);
+  var frames = getKeyframes(div);
 
   assert_equals(frames.length, 4, "number of frames");
 
-  const expected = [
+  var expected = [
     { offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
       color: "rgb(0, 0, 0)", marginTop: "8px" },
     { offset: 0.25, computedOffset: 0.25, easing: "ease", composite: "auto",
@@ -423,22 +422,22 @@ test(t => {
       color: "rgb(255, 255, 255)", marginTop: "16px" },
   ];
 
-  for (let i = 0; i < frames.length; i++) {
+  for (var i = 0; i < frames.length; i++) {
     assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
   }
 }, 'KeyframeEffect.getKeyframes() returns expected frames for an ' +
    'animation with different properties on different keyframes, all ' +
    'with the same easing function');
 
-test(t => {
-  const div = addDiv(t);
+test(function(t) {
+  var div = addDiv(t);
 
   div.style.animation = 'anim-different-props-and-easing 100s';
-  const frames = getKeyframes(div);
+  var frames = getKeyframes(div);
 
   assert_equals(frames.length, 4, "number of frames");
 
-  const expected = [
+  var expected = [
     { offset: 0, computedOffset: 0, easing: "linear", composite: "auto",
       color: "rgb(0, 0, 0)", marginTop: "8px" },
     { offset: 0.25, computedOffset: 0.25, easing: "steps(1)", composite: "auto",
@@ -449,44 +448,44 @@ test(t => {
       color: "rgb(255, 255, 255)", marginTop: "16px" },
   ];
 
-  for (let i = 0; i < frames.length; i++) {
+  for (var i = 0; i < frames.length; i++) {
     assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
   }
 }, 'KeyframeEffect.getKeyframes() returns expected frames for an ' +
    'animation with different properties on different keyframes, with ' +
    'a different easing function on each');
 
-test(t => {
-  const div = addDiv(t);
+test(function(t) {
+  var div = addDiv(t);
 
   div.style.animation = 'anim-merge-offset 100s';
-  const frames = getKeyframes(div);
+  var frames = getKeyframes(div);
 
   assert_equals(frames.length, 2, "number of frames");
 
-  const expected = [
+  var expected = [
     { offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
       color: "rgb(0, 0, 0)", marginTop: "8px" },
     { offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
       color: "rgb(255, 255, 255)", marginTop: "16px" },
   ];
 
-  for (let i = 0; i < frames.length; i++) {
+  for (var i = 0; i < frames.length; i++) {
     assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
   }
 }, 'KeyframeEffect.getKeyframes() returns expected frames for an ' +
    'animation with multiple keyframes for the same time, and all with ' +
    'the same easing function');
 
-test(t => {
-  const div = addDiv(t);
+test(function(t) {
+  var div = addDiv(t);
 
   div.style.animation = 'anim-merge-offset-and-easing 100s';
-  const frames = getKeyframes(div);
+  var frames = getKeyframes(div);
 
   assert_equals(frames.length, 3, "number of frames");
 
-  const expected = [
+  var expected = [
     { offset: 0, computedOffset: 0, easing: "steps(1)", composite: "auto",
       color: "rgb(0, 0, 0)", fontSize: "16px" },
     { offset: 0, computedOffset: 0, easing: "linear", composite: "auto",
@@ -496,22 +495,22 @@ test(t => {
       paddingLeft: "4px" },
   ];
 
-  for (let i = 0; i < frames.length; i++) {
+  for (var i = 0; i < frames.length; i++) {
     assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
   }
 }, 'KeyframeEffect.getKeyframes() returns expected frames for an ' +
    'animation with multiple keyframes for the same time and with ' +
    'different easing functions');
 
-test(t => {
-  const div = addDiv(t);
+test(function(t) {
+  var div = addDiv(t);
 
   div.style.animation = 'anim-no-merge-equiv-easing 100s';
-  const frames = getKeyframes(div);
+  var frames = getKeyframes(div);
 
   assert_equals(frames.length, 3, "number of frames");
 
-  const expected = [
+  var expected = [
     { offset: 0, computedOffset: 0, easing: "steps(1)", composite: "auto",
       marginTop: "0px", marginRight: "0px", marginBottom: "0px" },
     { offset: 0.5, computedOffset: 0.5, easing: "steps(1)", composite: "auto",
@@ -520,22 +519,22 @@ test(t => {
       marginTop: "20px", marginRight: "20px", marginBottom: "20px" },
   ];
 
-  for (let i = 0; i < frames.length; i++) {
+  for (var i = 0; i < frames.length; i++) {
     assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
   }
 }, 'KeyframeEffect.getKeyframes() returns expected frames for an ' +
    'animation with multiple keyframes for the same time and with ' +
    'different but equivalent easing functions');
 
-test(t => {
-  const div = addDiv(t);
+test(function(t) {
+  var div = addDiv(t);
 
   div.style.animation = 'anim-overriding 100s';
-  const frames = getKeyframes(div);
+  var frames = getKeyframes(div);
 
   assert_equals(frames.length, 6, "number of frames");
 
-  const expected = [
+  var expected = [
     { offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
       paddingTop: "30px" },
     { offset: 0.5, computedOffset: 0.5, easing: "ease", composite: "auto",
@@ -550,7 +549,7 @@ test(t => {
       paddingTop: "70px" },
   ];
 
-  for (let i = 0; i < frames.length; i++) {
+  for (var i = 0; i < frames.length; i++) {
     assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
   }
 }, 'KeyframeEffect.getKeyframes() returns expected frames for ' +
@@ -559,43 +558,43 @@ test(t => {
 // Gecko-specific test case: We are specifically concerned here that the
 // computed value for filter, "none", is correctly represented.
 
-test(t => {
-  const div = addDiv(t);
+test(function(t) {
+  var div = addDiv(t);
 
   div.style.animation = 'anim-filter 100s';
-  const frames = getKeyframes(div);
+  var frames = getKeyframes(div);
 
   assert_equals(frames.length, 2, "number of frames");
 
-  const expected = [
+  var expected = [
     { offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
       filter: "none" },
     { offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
       filter: "blur(5px) sepia(60%) saturate(30%)" },
   ];
 
-  for (let i = 0; i < frames.length; i++) {
+  for (var i = 0; i < frames.length; i++) {
     assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
   }
 }, 'KeyframeEffect.getKeyframes() returns expected values for ' +
    'animations with filter properties and missing keyframes');
 
-test(t => {
-  const div = addDiv(t);
+test(function(t) {
+  var div = addDiv(t);
 
   div.style.animation = 'anim-filter-drop-shadow 100s';
-  const frames = getKeyframes(div);
+  var frames = getKeyframes(div);
 
   assert_equals(frames.length, 2, "number of frames");
 
-  const expected = [
+  var expected = [
     { offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
       filter: "drop-shadow(rgb(0, 255, 0) 10px 10px 10px)" },
     { offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
       filter: "drop-shadow(rgb(255, 0, 0) 50px 30px 10px)" },
   ];
 
-  for (let i = 0; i < frames.length; i++) {
+  for (var i = 0; i < frames.length; i++) {
     assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
   }
 }, 'KeyframeEffect.getKeyframes() returns expected values for ' +
@@ -605,18 +604,18 @@ test(t => {
 // computed value for text-shadow and a "none" specified on a keyframe
 // are correctly represented.
 
-test(t => {
-  const div = addDiv(t);
+test(function(t) {
+  var div = addDiv(t);
 
   div.style.textShadow = '1px 1px 2px rgb(0, 0, 0), ' +
                          '0 0 16px rgb(0, 0, 255), ' +
                          '0 0 3.2px rgb(0, 0, 255)';
   div.style.animation = 'anim-text-shadow 100s';
-  const frames = getKeyframes(div);
+  var frames = getKeyframes(div);
 
   assert_equals(frames.length, 2, "number of frames");
 
-  const expected = [
+  var expected = [
     { offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
       textShadow: "rgb(0, 0, 0) 1px 1px 2px,"
                   + " rgb(0, 0, 255) 0px 0px 16px,"
@@ -625,7 +624,7 @@ test(t => {
       textShadow: "none" },
   ];
 
-  for (let i = 0; i < frames.length; i++) {
+  for (var i = 0; i < frames.length; i++) {
     assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
   }
 }, 'KeyframeEffect.getKeyframes() returns expected values for ' +
@@ -635,67 +634,67 @@ test(t => {
 // initial value for background-size and the specified list are correctly
 // represented.
 
-test(t => {
-  const div = addDiv(t);
+test(function(t) {
+  var div = addDiv(t);
 
   div.style.animation = 'anim-background-size 100s';
-  let frames = getKeyframes(div);
+  var frames = getKeyframes(div);
 
   assert_equals(frames.length, 2, "number of frames");
 
-  const expected = [
+  var expected = [
     { offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
-      backgroundSize: "auto" },
+      backgroundSize: "auto auto" },
     { offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
-      backgroundSize: "50%, 6px, contain" },
+      backgroundSize: "50% auto, 6px auto, contain" },
   ];
 
-  for (let i = 0; i < frames.length; i++) {
+  for (var i = 0; i < frames.length; i++) {
     assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
   }
 
   // Test inheriting a background-size value
 
   expected[0].backgroundSize = div.style.backgroundSize =
-    "30px, 40%, auto";
+    "30px auto, 40% auto, auto auto";
   frames = getKeyframes(div);
 
-  for (let i = 0; i < frames.length; i++) {
+  for (var i = 0; i < frames.length; i++) {
     assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i
                         + " after updating current style");
   }
 }, 'KeyframeEffect.getKeyframes() returns expected values for ' +
    'animations with background-size properties and missing keyframes');
 
-test(t => {
-  const div = addDiv(t);
+test(function(t) {
+  var div = addDiv(t);
   div.style.animation = 'anim-variables 100s';
 
-  const frames = getKeyframes(div);
+  var frames = getKeyframes(div);
 
   assert_equals(frames.length, 2, "number of frames");
 
-  const expected = [
+  var expected = [
     { offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
       transform: "none" },
     { offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
-      transform: "translate(100px)" },
+      transform: "translate(100px, 0px)" },
   ];
-  for (let i = 0; i < frames.length; i++) {
+  for (var i = 0; i < frames.length; i++) {
     assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
   }
 }, 'KeyframeEffect.getKeyframes() returns expected values for ' +
    'animations with CSS variables as keyframe values');
 
-test(t => {
-  const div = addDiv(t);
+test(function(t) {
+  var div = addDiv(t);
   div.style.animation = 'anim-variables-shorthand 100s';
 
-  const frames = getKeyframes(div);
+  var frames = getKeyframes(div);
 
   assert_equals(frames.length, 2, "number of frames");
 
-  const expected = [
+  var expected = [
     { offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
       marginBottom: "0px",
       marginLeft: "0px",
@@ -707,47 +706,47 @@ test(t => {
       marginRight: "100px",
       marginTop: "100px" },
   ];
-  for (let i = 0; i < frames.length; i++) {
+  for (var i = 0; i < frames.length; i++) {
     assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
   }
 }, 'KeyframeEffect.getKeyframes() returns expected values for ' +
    'animations with CSS variables as keyframe values in a shorthand property');
 
-test(t => {
-  const div = addDiv(t);
+test(function(t) {
+  var div = addDiv(t);
   div.style.animation = 'anim-custom-property-in-keyframe 100s';
 
-  const frames = getKeyframes(div);
+  var frames = getKeyframes(div);
 
   assert_equals(frames.length, 2, "number of frames");
 
-  const expected = [
+  var expected = [
     { offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
       color: "rgb(0, 0, 0)" },
     { offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
       color: "rgb(0, 255, 0)" },
   ];
-  for (let i = 0; i < frames.length; i++) {
+  for (var i = 0; i < frames.length; i++) {
     assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
   }
 }, 'KeyframeEffect.getKeyframes() returns expected values for ' +
    'animations with a CSS variable which is overriden by the value in keyframe');
 
-test(t => {
-  const div = addDiv(t);
+test(function(t) {
+  var div = addDiv(t);
   div.style.animation = 'anim-only-custom-property-in-keyframe 100s';
 
-  const frames = getKeyframes(div);
+  var frames = getKeyframes(div);
 
   assert_equals(frames.length, 2, "number of frames");
 
-  const expected = [
+  var expected = [
     { offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
-      transform: "translate(100px)" },
+      transform: "translate(100px, 0px)" },
     { offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
       transform: "none" },
   ];
-  for (let i = 0; i < frames.length; i++) {
+  for (var i = 0; i < frames.length; i++) {
     assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i);
   }
 }, 'KeyframeEffect.getKeyframes() returns expected values for ' +
@@ -1,11 +1,8 @@
 <!doctype html>
 <meta charset=utf-8>
-<title>CSSPseudoElement.getAnimations() for CSS animations</title>
-<!--  TODO: Add a more specific link for this once it is specified.  -->
-<link rel="help" href="https://drafts.csswg.org/css-animations-2/">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="support/testcommon.js"></script>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="../resources/testcommon.js"></script>
 <style>
 @keyframes anim1 { }
 @keyframes anim2 { }
   content: '';
 }
 </style>
+<body>
 <div id="log"></div>
 <script>
 'use strict';
 
-test(t => {
-  const div = addDiv(t, { class: 'before' });
-  const pseudoTarget = document.getAnimations()[0].effect.target;
+test(function(t) {
+  var div = addDiv(t, { class: 'before' });
+  var pseudoTarget = document.getAnimations()[0].effect.target;
   assert_equals(pseudoTarget.getAnimations().length, 1,
                 'Expected number of animations are returned');
   assert_equals(pseudoTarget.getAnimations()[0].animationName, 'anim1',