Skip to content

Commit

Permalink
fix: RN Gesture Handler Pressable support (#1746)
Browse files Browse the repository at this point in the history
  • Loading branch information
mdjastrzebski authored Feb 25, 2025
1 parent a9c056b commit bd78a26
Show file tree
Hide file tree
Showing 10 changed files with 222 additions and 72 deletions.
4 changes: 2 additions & 2 deletions examples/basic/components/__tests__/AnimatedView.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ describe('AnimatedView', () => {
);
expect(screen.root).toHaveStyle({ opacity: 0 });

await act(() => jest.advanceTimersByTime(250));
act(() => jest.advanceTimersByTime(250));
expect(screen.root).toHaveStyle({ opacity: 1 });
});

Expand All @@ -32,7 +32,7 @@ describe('AnimatedView', () => {
);
expect(screen.root).toHaveStyle({ opacity: 0 });

await act(() => jest.advanceTimersByTime(250));
act(() => jest.advanceTimersByTime(250));
expect(screen.root).toHaveStyle({ opacity: 1 });
});
});
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"chalk": "^4.1.2",
"jest-matcher-utils": "^29.7.0",
"pretty-format": "^29.7.0",
"react-native-gesture-handler": "^2.23.1",
"redent": "^3.0.0"
},
"peerDependencies": {
Expand Down
8 changes: 4 additions & 4 deletions src/__tests__/react-native-animated.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,28 +43,28 @@ describe('AnimatedView', () => {
jest.useRealTimers();
});

it('should use native driver when useNativeDriver is true', async () => {
it('should use native driver when useNativeDriver is true', () => {
render(
<AnimatedView fadeInDuration={250} useNativeDriver={true}>
Test
</AnimatedView>,
);
expect(screen.root).toHaveStyle({ opacity: 0 });

await act(() => jest.advanceTimersByTime(250));
act(() => jest.advanceTimersByTime(250));
// This stopped working in tests in RN 0.77
// expect(screen.root).toHaveStyle({ opacity: 0 });
});

it('should not use native driver when useNativeDriver is false', async () => {
it('should not use native driver when useNativeDriver is false', () => {
render(
<AnimatedView fadeInDuration={250} useNativeDriver={false}>
Test
</AnimatedView>,
);
expect(screen.root).toHaveStyle({ opacity: 0 });

await act(() => jest.advanceTimersByTime(250));
act(() => jest.advanceTimersByTime(250));
expect(screen.root).toHaveStyle({ opacity: 1 });
});
});
61 changes: 61 additions & 0 deletions src/__tests__/react-native-gesture-handler.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import 'react-native-gesture-handler/jestSetup.js';
import React from 'react';
import { View } from 'react-native';
import { Pressable } from 'react-native-gesture-handler';

import { fireEvent, render, screen, userEvent } from '..';
import { createEventLogger, getEventsNames } from '../test-utils';

test('fireEvent can invoke press events for RNGH Pressable', () => {
const onPress = jest.fn();
const onPressIn = jest.fn();
const onPressOut = jest.fn();
const onLongPress = jest.fn();

render(
<View>
<Pressable
testID="pressable"
onPress={onPress}
onPressIn={onPressIn}
onPressOut={onPressOut}
onLongPress={onLongPress}
/>
</View>,
);

const pressable = screen.getByTestId('pressable');

fireEvent.press(pressable);
expect(onPress).toHaveBeenCalled();

fireEvent(pressable, 'pressIn');
expect(onPressIn).toHaveBeenCalled();

fireEvent(pressable, 'pressOut');
expect(onPressOut).toHaveBeenCalled();

fireEvent(pressable, 'longPress');
expect(onLongPress).toHaveBeenCalled();
});

test('userEvent can invoke press events for RNGH Pressable', async () => {
const { events, logEvent } = createEventLogger();
const user = userEvent.setup();

render(
<View>
<Pressable
testID="pressable"
onPress={logEvent('press')}
onPressIn={logEvent('pressIn')}
onPressOut={logEvent('pressOut')}
onLongPress={logEvent('longPress')}
/>
</View>,
);

const pressable = screen.getByTestId('pressable');
await user.press(pressable);
expect(getEventsNames(events)).toEqual(['pressIn', 'pressOut', 'press']);
});
34 changes: 33 additions & 1 deletion src/user-event/press/__tests__/longPress.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react';
import { Pressable, Text, TouchableHighlight, TouchableOpacity } from 'react-native';
import { Pressable, Text, TouchableHighlight, TouchableOpacity, View } from 'react-native';
import type { ReactTestInstance } from 'react-test-renderer';

import { render, screen } from '../../..';
import { createEventLogger, getEventsNames } from '../../../test-utils';
Expand Down Expand Up @@ -152,4 +153,35 @@ describe('userEvent.longPress with fake timers', () => {

expect(mockOnLongPress).toHaveBeenCalled();
});

test('longPress accepts custom duration', async () => {
const { events, logEvent } = createEventLogger();
const user = userEvent.setup();

render(
<Pressable
onPress={logEvent('press')}
onPressIn={logEvent('pressIn')}
onPressOut={logEvent('pressOut')}
onLongPress={logEvent('longPress')}
testID="pressable"
/>,
);

await user.longPress(screen.getByTestId('pressable'), { duration: 50 });
expect(getEventsNames(events)).toEqual(['pressIn', 'press', 'pressOut']);
});

it('longPress throws on composite components', async () => {
render(<View testID="view" />);
const user = userEvent.setup();

const compositeView = screen.getByTestId('view').parent as ReactTestInstance;
await expect(user.longPress(compositeView)).rejects.toThrowErrorMatchingInlineSnapshot(`
"longPress() works only with host elements. Passed element has type "function Component() {
(0, _classCallCheck2.default)(this, Component);
return _callSuper(this, Component, arguments);
}"."
`);
});
});
6 changes: 4 additions & 2 deletions src/user-event/press/__tests__/press.real-timers.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ describe('userEvent.press with real timers', () => {
);

await user.press(screen.getByTestId('pressable'));
// Typical event order is pressIn, pressOut, press
// But sometimes due to a race condition, the order is pressIn, press, pressOut.
const eventSequence = getEventsNames(events).join(', ');
expect(
eventSequence === 'pressIn, pressOut, press' || eventSequence === 'pressIn, press, pressOut',
Expand Down Expand Up @@ -201,11 +203,11 @@ describe('userEvent.press with real timers', () => {
);
await user.press(screen.getByTestId('pressable'));

const eventsNames = getEventsNames(events).join(', ');
const eventSequence = getEventsNames(events).join(', ');
// Typical event order is pressIn, pressOut, press
// But sometimes due to a race condition, the order is pressIn, press, pressOut.
expect(
eventsNames === 'pressIn, pressOut, press' || eventsNames === 'pressIn, press, pressOut',
eventSequence === 'pressIn, pressOut, press' || eventSequence === 'pressIn, press, pressOut',
).toBe(true);
});

Expand Down
14 changes: 14 additions & 0 deletions src/user-event/press/__tests__/press.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
TouchableOpacity,
View,
} from 'react-native';
import type { ReactTestInstance } from 'react-test-renderer';

import { render, screen } from '../../..';
import { createEventLogger, getEventsNames } from '../../../test-utils';
Expand Down Expand Up @@ -331,6 +332,19 @@ describe('userEvent.press with fake timers', () => {
expect(mockOnPress).toHaveBeenCalled();
});

it('press throws on composite components', async () => {
render(<View testID="view" />);
const user = userEvent.setup();

const compositeView = screen.getByTestId('view').parent as ReactTestInstance;
await expect(user.press(compositeView)).rejects.toThrowErrorMatchingInlineSnapshot(`
"press() works only with host elements. Passed element has type "function Component() {
(0, _classCallCheck2.default)(this, Component);
return _callSuper(this, Component, arguments);
}"."
`);
});

test('disables act environmennt', async () => {
// In this test there is state update during await when typing
// Since wait is not wrapped by act there would be a warning
Expand Down
Loading

0 comments on commit bd78a26

Please sign in to comment.