mirror of
https://github.com/callstack/react-native-testing-library.git
synced 2026-09-18 23:09:04 +08:00
feat: support pointerEvents (#655)
* test: add pointerEvents test * feat: add pointerEvents handling * test: add test for nested views * feat: add pointerEvents box-none handling * test: handle auto pointerEvents * Update src/__tests__/fireEvent.test.js Co-authored-by: Michał Pierzchała <thymikee@gmail.com>
This commit is contained in:
@@ -234,6 +234,83 @@ test('should not fire on non-editable TextInput with nested Text', () => {
|
||||
expect(onChangeTextMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('should not fire on none pointerEvents View', () => {
|
||||
const handlePress = jest.fn();
|
||||
|
||||
const screen = render(
|
||||
<View pointerEvents="none">
|
||||
<Pressable onPress={handlePress}>
|
||||
<Text>Trigger</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
);
|
||||
|
||||
fireEvent.press(screen.getByText('Trigger'));
|
||||
expect(handlePress).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('should not fire on box-only pointerEvents View', () => {
|
||||
const handlePress = jest.fn();
|
||||
|
||||
const screen = render(
|
||||
<View pointerEvents="box-only">
|
||||
<Pressable onPress={handlePress}>
|
||||
<Text>Trigger</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
);
|
||||
|
||||
fireEvent.press(screen.getByText('Trigger'));
|
||||
expect(handlePress).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('should fire on box-none pointerEvents View', () => {
|
||||
const handlePress = jest.fn();
|
||||
|
||||
const screen = render(
|
||||
<View pointerEvents="box-none">
|
||||
<Pressable onPress={handlePress}>
|
||||
<Text>Trigger</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
);
|
||||
|
||||
fireEvent.press(screen.getByText('Trigger'));
|
||||
expect(handlePress).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('should fire on auto pointerEvents View', () => {
|
||||
const handlePress = jest.fn();
|
||||
|
||||
const screen = render(
|
||||
<View pointerEvents="auto">
|
||||
<Pressable onPress={handlePress}>
|
||||
<Text>Trigger</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
);
|
||||
|
||||
fireEvent.press(screen.getByText('Trigger'));
|
||||
expect(handlePress).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('should not fire on box-only pointerEvents View with nested elements', () => {
|
||||
const handlePress = jest.fn();
|
||||
|
||||
const screen = render(
|
||||
<View pointerEvents="box-only">
|
||||
<View>
|
||||
<Pressable onPress={handlePress}>
|
||||
<Text>Trigger</Text>
|
||||
</Pressable>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
|
||||
fireEvent.press(screen.getByText('Trigger'));
|
||||
expect(handlePress).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('should pass event up on disabled TouchableOpacity', () => {
|
||||
const handleInnerPress = jest.fn();
|
||||
const handleOuterPress = jest.fn();
|
||||
|
||||
@@ -17,11 +17,29 @@ const isTouchResponder = (element?: ReactTestInstance) => {
|
||||
return !!element?.props.onStartShouldSetResponder || isTextInput(element);
|
||||
};
|
||||
|
||||
const isPointerEventEnabled = (
|
||||
element?: ReactTestInstance,
|
||||
isParent?: boolean
|
||||
) => {
|
||||
const parentCondition = isParent
|
||||
? element?.props.pointerEvents === 'box-only'
|
||||
: element?.props.pointerEvents === 'box-none';
|
||||
|
||||
if (element?.props.pointerEvents === 'none' || parentCondition) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!element?.parent) return true;
|
||||
|
||||
return isPointerEventEnabled(element.parent, true);
|
||||
};
|
||||
|
||||
const isEventEnabled = (
|
||||
element?: ReactTestInstance,
|
||||
touchResponder?: ReactTestInstance
|
||||
) => {
|
||||
if (isTextInput(element)) return element?.props.editable !== false;
|
||||
if (!isPointerEventEnabled(element)) return false;
|
||||
|
||||
const touchStart = touchResponder?.props.onStartShouldSetResponder?.();
|
||||
const touchMove = touchResponder?.props.onMoveShouldSetResponder?.();
|
||||
|
||||
Reference in New Issue
Block a user