diff --git a/packages/react-native/Libraries/Animated/__tests__/Animated-itest.js b/packages/react-native/Libraries/Animated/__tests__/Animated-itest.js index f5f12302f4c..f353d8c26df 100644 --- a/packages/react-native/Libraries/Animated/__tests__/Animated-itest.js +++ b/packages/react-native/Libraries/Animated/__tests__/Animated-itest.js @@ -598,3 +598,99 @@ test('AnimatedValue.interpolate', () => { expect(viewElement.getBoundingClientRect().x).toBe(0.5); expect(viewElement.getBoundingClientRect().y).toBe(75); }); + +test('Animated.sequence', () => { + let _translateY; + let _isSequenceFinished = false; + const elementRef = createRef(); + + function MyApp() { + const translateY = useAnimatedValue(0, {useNativeDriver: true}); + _translateY = translateY; + + return ( + + + + ); + } + + const root = Fantom.createRoot(); + + Fantom.runTask(() => { + root.render(); + }); + + const element = ensureInstance(elementRef.current, ReactNativeElement); + + expect(element.getBoundingClientRect().y).toBe(0); + + Fantom.runTask(() => { + Animated.sequence([ + Animated.timing(_translateY, { + toValue: 1, + duration: 500, + useNativeDriver: true, + }), + Animated.timing(_translateY, { + toValue: 0, + duration: 0, + useNativeDriver: true, + }), + ]).start(({finished}) => { + if (finished) { + _isSequenceFinished = true; + } + }); + }); + + Fantom.unstable_produceFramesForDuration(500); + + expect( + // $FlowFixMe[incompatible-use] + Fantom.unstable_getDirectManipulationProps(element).transform[0].translateY, + ).toBeCloseTo(-16, 0.001); + + if (!ReactNativeFeatureFlags.cxxNativeAnimatedRemoveJsSync()) { + Fantom.runWorkLoop(); // React update to sync end state of 1st timing animation in sequence + } + expect(_isSequenceFinished).toBe(false); + expect(element.getBoundingClientRect().y).toBe(-16); + + Fantom.runWorkLoop(); // React render + + expect( + // $FlowFixMe[incompatible-use] + Fantom.unstable_getDirectManipulationProps(element).transform[0].translateY, + ).toBeCloseTo(0, 0.001); + + if (!ReactNativeFeatureFlags.cxxNativeAnimatedRemoveJsSync()) { + Fantom.runWorkLoop(); // React update to sync end state of 2nd timing animation in sequence + } + expect(element.getBoundingClientRect().y).toBe(0); + + if (ReactNativeFeatureFlags.cxxNativeAnimatedRemoveJsSync()) { + expect(_isSequenceFinished).toBe(false); + Fantom.runWorkLoop(); + } + expect(_isSequenceFinished).toBe(true); +});