callstack / react-native-testing-library

🦉 Simple and complete React Native testing utilities that encourage good testing practices.
https://callstack.github.io/react-native-testing-library/
MIT License
3.05k stars 271 forks source link

Add support for switch to toBeChecked matcher #1656

Closed sladek-jan closed 1 week ago

sladek-jan commented 1 week ago

Describe the Feature

Possible Implementations

Related Issues

https://github.com/callstack/react-native-testing-library/issues/1457

mdjastrzebski commented 1 week ago

I will have to consider what is the best value to solve the Switch checking problem.

The Switch component in React Native codebase does not actually rely on the checked state. See: https://github.com/facebook/react-native/blob/3350050edc6bdec1652448863ab0c6872d2ac4ed/packages/react-native/Libraries/Components/Switch/Switch.js#L188

It uses value for that, and setting this prop does to affect the accessibilityState prop:

        <RCTSwitch
          accessibilityRole="switch"
          onChange={[Function handleChange]}
          onResponderTerminationRequest={[Function returnsFalse]}
          onStartShouldSetResponder={[Function returnsTrue]}
          style={
            {
              "height": 31,
              "width": 51,
            }
          }
          testID="switch"
          value={true}
        />,

This is different then web, where switch role is related to the checked prop: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/switch_role

Perhaps this should (also) be handled at the RN repo level.

mdjastrzebski commented 1 week ago

Yeah, you have a point there. Let's fix it. 🔨 The implementation is slightly more complex tough.

sladek-jan commented 1 week ago

Ok, thank you! For now, I solved it using this snippet as a workaround:

const expectSwitchToBeChecked = (instance: ReactTestInstance, checked: boolean) => {
    expect(instance.props.accessibilityState.checked).toBe(checked);
};
mdjastrzebski commented 1 week ago

@sladek-jan from my research, for native Switch element you should examine element.props.value instead of accessibilityState which afaik is not set by the Switch control itself.

mdjastrzebski commented 1 week ago

@sladek-jan Just for clarity which switch component are you using? Switch from React Native package or something else?

sladek-jan commented 1 week ago

Ah, sorry for the confusion, we are using a design library in the project and under the hood, it renders a custom View with the role 'switch', which is controlled by setting the 'aria-checked' prop. So my workaround probably doesn't apply to the real RN Switch.

mdjastrzebski commented 1 week ago

nvm, let's ship both Switch element and switch role 🤣