-
Notifications
You must be signed in to change notification settings - Fork 273
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
Non-visible modal content shows up in queries #659
Comments
I think it's due to the fact that the getBy and queryBy queries parse the DOM itself. The modal is always in the DOM, its appearance to the user is dictated by its Personally what I usually tend to do in those cases is check the I think a better solution might be to abstract this hack (checking the visible prop) in an extension of jest expect method, that could be put in the jest native repo for example. |
Yeah that makes sense. Thanks for taking a look. Testing the I suppose this is more of a feature request given the context (and would probably be a breaking change). Maybe this will bug me enough to try implementing it at some point 😄 |
Totally understand your point of view. Unfortunately I think it's deeply tied to the modal implementation with the visible prop. In my mind, changing the getByText query to take into account the modal would imply checking all the parents of the node until you find (or not) a modal right? |
There's a possibility that Modal sets some accessibility props for visibility. Our queries should take those into account. It's quite irritating when testing React Navigation, which keeps previous screens mounted, but disabled for accessibility. |
@thymikee I did not know that could happen while testing navigation, I can see how that could be a problem. Do you want to have a fix that would check both React native modals as well as previously mounted react navigation pages? |
If this can be done solely with accessibility props available on these components, then I'm all for it! |
I think I ran into this same issue and pointed it out here. It seems |
@thymikee you were right for react navigation, it does use accessibility props for its screen. It uses accessibilityElementsHidden for ios and importantForAccessibility for android. I think we could use either of them in our use case but For the modal from react-native, there is no accessibility prop according to the props given in the doc. Its prop |
I'd be in favor of such a behavior as a default one. If someone needs to access hidden element, they could do it using the |
The other option is to send a PR to React Native adding accessibility props for Modal. |
I just wanted to confirm if possible that the issue I mentioned here is related to this issue. It seems that it is not only the modal that gets picked up in queries, but any non-visible component. How do people get around this when using |
Yes it seems related to your issue @joe307bad. To fix it, we were discussing if we could base queries like getBytext on accessibility props so that it would ignore any non visible element. @thymikee here are the 3 possible solutions I see for getByText for instance. GetByText uses
Do you see other options? Which one do you prefer? (I think the simplest one would be the first) |
@MattAgn, I would love to try my hand at implementing the first solution. Could you point me in the direction of the |
any progress on this? Or at least a decision on which option to take from @MattAgn's list above? I have been digging into the codebase a bit. Not sure how the first option in @MattAgn 's list would be implemented. I might be misunderstanding how the dependency injection is being accomplished but it seems the function findAllByQuery(instance: ReactTestInstance) {
return function findAllFn(
args: QueryArg,
waitForOptions?: WaitForOptions = {}
) {
return waitFor(() => getAllByQuery(instance)(args), waitForOptions);
};
} The function |
I just opened a PR on react-native repository to update the mock so the Modal doesn't render its children when the visible prop is false. It should fix your issue :) |
…#32346) Summary: The Modal's mock always render its children (whether it is visible or not), whereas in reality the Modal renders `null` when the Modal is not visible. This causes troubles when trying to test whether the Modal is visible or not. Instead of testing if the children are rendered (using getByText from React Native Testing Library for instance), we are forced to test the value of the visible prop directly (see callstack/react-native-testing-library#508 and callstack/react-native-testing-library#659). This is not ideal because we are forced to test implementation detail and can't test from the user perspective. I also believe the mock should be closest as possible from reality. I had 2 options: 1. Rendering the Modal without its children 2. Not rendering the Modal at all The latter has the advantage of being closer to the reality, but I chose the former to still be able to test the Modal through the visible prop, so there is no breaking change (only snapshots update will be required). ## Changelog [General] [Changed] - Update Modal's mock to not render its children when it is not visible Pull Request resolved: #32346 Test Plan: I added a test case when visible is false, then updated the mock so the children are not rendered. The before / after is here: ![image](https://user-images.githubusercontent.com/17070498/136256142-a351d002-8b77-490a-ba65-1e8ad0d6eb55.png) Reviewed By: yungsters Differential Revision: D31445964 Pulled By: lunaleaps fbshipit-source-id: 08501921455728cde6befd0103016c95074cc1df
This ever get fixed? |
@OliverAThunes It should be fixed in RN 0.67.4 |
I'm currently facing the issue described in this comment. We're working on something similar to "Flows" outlined in this article - where we can test our app and its user journeys to add confidence/reliability to each PR before it is merged. TL;DR -> Entire app testing with Navigation (mocking network requests using MSW). While Detox exists, it has limitations that prevent it from running on every PR - mainly the compile times per platform. We're willing to accept that trade off of "native env" for the ability to write comprehensive tests for the JS flows of our app. While this is exciting:
I'm curious if there is any progress towards enhancing the API like in #787 . The modal not showing children is nice - but the problem still exists where the entire stack is rendered behind the "current active screen". This results in querying returning multiple results when there should be only one (as described in the issue). At the moment I'm trying to work around this somehow. The current train of thought is to figure out how to dynamically add a Even that idea though has its limitations. Navigating using I can't imagine the React Navigation implementation would change to support this limitation. So I'm wondering if the queries could ignore screens not visible to the user while still being able to navigate to screens behind the current one if necessary? |
Closing as superseded by #970, which should provide a solution to the more generalised issues that the hidden screens content, e.g. when using stack navigator from React Navigation, is queried by RNTL by default. As a partial solution/workaround you can const detailsScreen = within(screen.getByTestId('screen-details'));
// Now you can issue queries limited to elements under 'detailsScreens'
expect(detailsScreen.getByText(...)).toBeTruthy(); |
I'm still running into trouble with this. This is using @mdjastrzebski 's solution:
|
@cfradella If you need to match a hidden element (your modal considered hidden as it has screen.getByTestId("particleAnimation", { includeHiddenElements: true }) Note: the solution you mentioned above is stale and referred to pre v12 versions of RNTL. Additionally, we no longer recommend using expect(screen.getByTestId("particleAnimation", { includeHiddenElements: true })).toBeOnTheScreen() |
That worked, thanks for saving my day. : 👍 |
Describe the bug
Hi, thanks for taking a look at this!
I'm fairly new to react-native, but have a lot of experience with web testing-library variants and ran across some unexpected (to me) behavior. Query methods find nodes in non-visible modals.
I think this is what this user was getting at #508
Steps to Reproduce
Here's a simple example test I set up to test this out
Expected behavior
I'd expect this test to pass, since there's no modal content visible to the user while the modal is not visible.
If this is expected behavior, is there a recommended way to test appearance/disappearance modals?
Versions
@testing-library/react-native@7.1.0
The text was updated successfully, but these errors were encountered: