-
Notifications
You must be signed in to change notification settings - Fork 278
fix: press event order #1696
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: press event order #1696
Conversation
@pierrezimmermannbam I'm messing with User Event |
@mdjastrzebski: interesting observation in regards to 'short' presses. I was able to reproduce this in my own experimentation too. Do you know if this phenomenon is documented somewhere (whether that be actual documentation or a reference to source code)? |
@winghouchan The best source is probably Pressability code: https://github.com/facebook/react-native/blob/33e1ae13f88979d8346e4f5ddd4cbce500a16999/packages/react-native/Libraries/Pressability/Pressability.js#L342 There is the code path when Then there is the code path for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work investigating the issue! The fix is correct but I suggested a slightly different approach
This PR has been released in v12.8.1 🎉 |
Since these changes, I have issues on some tests when using |
@cartok What kind of issues are you having with user event? |
@mdjastrzebski Thanks for reply. I can no longer reproduce it. Must've been something with my test environment. Maybe related to the jest vscode extension. |
I also have a test case which is failing with 12.8.1 and passing with 12.8.0 - A bit unexpected that a patch increment can break something on the consumer side. Simplified test looks like this - The screen makes an API call on first render, and then again after pull to refresh (using standard it('clears loading state after loading is done and pull to refresh', async () => {
render(<TestScreen />);
await waitForElementToBeRemoved(() => screen.getByTestId('loading-skeleton'));
const scrollView = screen.getByTestId('scroll-view');
fireEvent(scrollView.props.refreshControl, 'onRefresh');
await waitForElementToBeRemoved(() => screen.getByTestId('loading-skeleton'));
expect(Api.getFooBar).toHaveBeenCalledTimes(2);
}); Is there a better way to interact with RefreshControl/onRefresh in a pull to refresh scenario? Any idea why 12.8.1 breaks this? Thank you! |
Ah interesting, after doing a bit more investigation, I found the root cause is related to those 3 added lines that check if the element is mounted: function fireEvent(element: ReactTestInstance, eventName: EventName, ...data: unknown[]) {
if (!isElementMounted(element)) {
return;
}
// ... Maybe there is something wrong with the way I query the element? Why would |
Looks like you are trying to fire event on a prop (refresh control), which is a React.Element type (description of React component to be rendered), Fire Event, and most other RNTL APIs expect to be called on ReactTestInstance, rendered React component. As a workaround, you can try to either:
|
Thanks for the quick reply @mdjastrzebski!
Yes, that makes sense. Regarding the workarounds, assigning a testID also does not work, it is not able to find the element (I assume it is never "really" rendered). Using the chained props access really doesn't look good which is why I would prefer fireEvent syntax. I understand it doesn't make sense to use it on an "unmounted" element. The next and real question is why is RefreshControl never rendered/mounted. |
So, is there more "RNTL way" to interact with |
WIP #1822 |
Summary
Resolves: #1687
Reverses
pressOut
andpress
event order so that it matches experimental data for regular presses:pressIn
,pressOut
press
.The previous setup matched edge case for very short (< 130ms) presses, when order was:
pressIn
press
pressOut
Scope
See experiments: https://github.com/callstack/react-native-testing-library/wiki/Press-Events
Test plan
All tests pass