callstack / react-native-testing-library

🦉 Simple and complete React Native testing utilities that encourage good testing practices.
https://callstack.github.io/react-native-testing-library/
MIT License
3.01k stars 264 forks source link

Unexpected behavior of userEvent.press with timers #1583

Closed ardentum-c closed 3 months ago

ardentum-c commented 3 months ago

Describe the bug

Hello! I was playing with some async press handlers for my component, and noticed a weird behavior. It seems like DEFAULT_MIN_PRESS_DURATION from /src/user-event/press/constants.ts affects jest timers in an unexpected way and makes it difficult to test press events in combination with timers.

Here is a synthetic test case that reproduces the bug. Right now it works only because I am subtracting 130ms (PRESSABLE_DELAY) from the expected time to wait for.

    function DelayedPressable(props: {
      onPress: () => void;
      delay: number;
    }): React.JSX.Element {
      return (
        <Pressable
          testID="pressable"
          onPress={() => {
            setTimeout(props.onPress, props.delay);
          }}
        />
      );
    }

  it("should call the provided onPress callback after provided delay", async () => {
    jest.useFakeTimers();
    const user = userEvent.setup();
    const handlePress = jest.fn(() => {});
    const delay = 1000;

    // The assertion below fails if 0 is assigned here
    const PRESSABLE_DELAY = 130;

    render(<DelayedPressable onPress={handlePress} delay={delay} />);

    await user.press(screen.getByTestId("pressable"));
    await act(async () =>
      jest.advanceTimersByTimeAsync(delay - PRESSABLE_DELAY - 1),
    );

    expect(handlePress).not.toHaveBeenCalled();
  });

Expected behavior

I am not sure what is the best way to handle that, but the current behavior is confusing and requires an investigation from a developer to understand what is happening.

Maybe it should use the Pressable's unstable_pressDelay prop?

Versions

    @testing-library/react-native: ^12.4.4 => 12.4.5 
    react: 18.2.0 => 18.2.0 
    react-native: 0.73.6 => 0.73.6 
    react-test-renderer: 18.2.0 => 18.2.0 
ardentum-c commented 3 months ago

Please, just delete the issue. (Sorry for that mess) I've accidently submitted the form by a hotkey, tried to make it more meaningful, but decided to take a step back and investigate the issue more by myself.

I guess there is still some weird behavior here, but don't want to bother you with poorly prepared issue report. Will return in case there will be more.