You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Querying by role with name on nested touchables return multiple elements #1152
We have a problem when querying nested touchables, see the example for more details:
describe('nested touchables',()=>{it('conflicting elements',()=>{const{ getByRole }=render(<PressableaccessibilityRole="button"><Text>Some other text</Text><PressableaccessibilityRole="button"><Text>Save</Text></Pressable></Pressable>);// Found multiple elements with accessibilityRole: button// Here I'm not sure what we should do. This is not an accessible pattern.// At least we should suggest a better error (might be just a warning/error on nested touchables)expect(getByRole('button',{name: 'Save'})).toBeTruthy();});it('with accessible={false}',()=>{const{ getByRole }=render(<PressableaccessibilityRole="button"accessible={false}><Text>Some other text</Text><PressableaccessibilityRole="button"><Text>Save</Text></Pressable></Pressable>);// Found multiple elements with accessibilityRole: button// Here it should work and only getting the lower Pressable.// `accessible={false}` means it won't be read to the screen-reader.// This is a common pattern I've seen where you make a whole area implicitly touchable for better UX// but add a nested explicit button for better discoverability (and accessibility)expect(getByRole('button',{name: 'Save'})).toBeTruthy();});});
Essentially for any case when component structure allows for nesting elements matching query predicate, it currently will result in matching both the inner and outer one. This might be more visible in certain scenarios like *ByRole queries, but probably affects all nesting scenarios.
It seems that RTL/DTL should behave the same as our code because their queries rely on using querySelectorAll which seems to have the same behavior of returning both outer and inner for nested elements.
I think we should first investigate how RTL would behave in a similar case, and then decide if this is a bug or a feature. @AugustinLF wdyt?
Overall I agree, that sounds fair and we should probably use the same API/behaviour. I do think the accessible={true} might be a special case, even though ideally the developer would use an onPress with a role on the parent element.
Regarding the original tests mentioned in this issue, we should consider excluding elements with explicit accessible={false} prop from *ByRole query, since these are explicitly marked as not being accessibility elements, and afaiu should not have a role.
Activity
mdjastrzebski commentedon Sep 29, 2022
I think that this might actually be a more general aspect of out tree walking code that uses
findAllfrom RTR.I imagine that it also should manifest itself for any scenario with matching nested elements, like:
*ByLabelwith following setup:or
*ByA11yStateswith following setup:Essentially for any case when component structure allows for nesting elements matching query predicate, it currently will result in matching both the inner and outer one. This might be more visible in certain scenarios like
*ByRolequeries, but probably affects all nesting scenarios.It seems that RTL/DTL should behave the same as our code because their queries rely on using
querySelectorAllwhich seems to have the same behavior of returning both outer and inner for nested elements.I think we should first investigate how RTL would behave in a similar case, and then decide if this is a bug or a feature.
@AugustinLF wdyt?
AugustinLF commentedon Sep 29, 2022
Overall I agree, that sounds fair and we should probably use the same API/behaviour. I do think the
accessible={true}might be a special case, even though ideally the developer would use anonPresswith a role on the parent element.mdjastrzebski commentedon Sep 30, 2022
Regarding the original tests mentioned in this issue, we should consider excluding elements with explicit
accessible={false}prop from*ByRolequery, since these are explicitly marked as not being accessibility elements, and afaiu should not have a role.@AugustinLF wdyt?
AugustinLF commentedon Oct 1, 2022
Yes, I think that'd be a great start!
mdjastrzebski commentedon Oct 17, 2022
Closing in favour of #1180 with more clear scope.