react-nativereact-native-testing-library

React Native Testing Library: scroll FlatList to bottom


I have a react-native FlatList component with onEndReached event used to load more items.

I am testing the component with react-native-testing-library. The test is as follows:

Test was failing because FlatList was not rendering new items even thought FlatList's data property was being updated (I used act and waitFor as needed).

I managed to make the test pass when I fired onScroll event to bottom after some tries with hardcoded values.

Is there a way to make a helper to scroll to bottom taking into account proper FlatList size?

Helper to improve:

export const scrollListToBottom = (list: ReactTestInstance) => {
  // FIXME: improve to get real list size
  // After some tries these hardcoded values allowed to pass the test
  act(() => {
    fireEvent.scroll(list, {
      nativeEvent: {
        contentSize: {height: 500, width: 100},
        contentOffset: {y: 400, x: 0},
        layoutMeasurement: {height: 100, width: 100},
      }
    })
  })

  // FIXME: if onScroll works perfectly is this even needed?
  act(() => {
    fireEvent(list, 'onEndReached')
  })
}

Thank you.


Solution

  • import { act, fireEvent } from '@testing-library/react-native';
    
    export const scrollListToBottom = async (list) => {
      // Find the scrollable view within the FlatList
      const scrollableView = list.findByProps({ testID: 'flatlist-scrollable' });
    
      // Get the height of the content within the FlatList
      const contentHeight = scrollableView.props.contentSize.height;
    
      // Calculate the scroll position to reach the bottom
      const scrollPosition = {
        x: 0, // Horizontal scroll position
        y: contentHeight, // Scroll to the calculated content height
      };
    
      // Scroll to the calculated position
      await act(async () => {
        fireEvent.scroll(scrollableView, { contentOffset: scrollPosition });
      });
    
      // Trigger the onEndReached event
      await act(async () => {
        fireEvent(list, 'onEndReached');
      });
    };