Description
Describe the Feature
This is a proposed tweak to *ByRole
query. It can be treated as either a fix or a (breaking) change.
Currently getByRole
query is based on explicit role set in accessibilityRole
prop. Other props are not taken into account (at least until #1064 is merged). This behaviour while basic can be problematic as according to screen readers, elements with accessible={false}
(either explicit or implicit) are not focusable by screen reader.
This manifests in relatively common RN pattern:
<Pressable accessibilityRole="button" accessible={false}>
<Text>Cell title</Text>
<Pressable accessibilityRole="button">
<Text>Action</Text>
</Pressable>
</Pressable>
Under current implementation getByRole('button', { name: "Action" })
would select both outer and inner pressables. After implementing the proposed change it would select only the inner one.
Possible Implementations
- element can be matched by
getByRole
using the same criteria as now (host component, equalaccessibilityRole
) but also needs to be consideredaccessibility element
(i.e. be focusable). - each host view can be made focusable by explicitly passing
accessible={true}
- some host view types are considered focusable without the
accessible
prop (e.g.Text
,TextInput
), but can have their "focusability" disabled by settingaccessible={false}
- basic host
View
is not consider focusable - some RN built in components, e.g.
Pressable
,TouchableOpacity
which render to hostView
actually set explicitaccessible={true}
prop on the view
In more practical terms we could use something like isAccessibilityElement
to check for focusable state:
export function isAccessibilityElement(
element: ReactTestInstance | null
): boolean {
if (element == null) {
return false;
}
if (element.props.accessible !== undefined) {
return element.props.accessible;
}
return (
isHostElementForType(element, Text) ||
isHostElementForType(element, TextInput)
);
}
Then this criteria should be added to *ByRole
query.
This change should not affect other general purpose queries as *ByText
or *ByTestId
. It may be worth considering applying it to some other a11y-related queries, which would make only sense if selected view is accessible: *ByA11yValue
, *ByA11State
.
Related Issues
#1152 - initial source for issue
#1163 - related discussion
#1064 - hidden query option