instea/react-native-popup-menu

e2e testing using testID and customStyles

mikbry opened this issue · 14 comments

This component is not designed for e2e testing, see #155.
But i found a workaround using customStyles. In fact customStyles are more customProps for sub-components.
For MenuTrigger:

<MenuTrigger customStyles={{ triggerTouchable: { testID: 'menu-trigger' } }} />

For MenuOption:

<MenuOption customStyles={{ optionTouchable: { testID: 'option-1' } }} />

Tested using Detox on Android emulator

This works for MenuTrigger, but no testID is showing up for MenuOption for me. I'm using Jest and React Native.

For me it is working ok testing 4/5 different MenuOptions. And I checked back at MenuOptions source code:

<Touchable
          onPress={() => this._onSelect()}
          {...defaultTouchableProps}
          {...customStyles.optionTouchable}
        >
          {rendered}
</Touchable>

So optionTouchable is the right parameter. Are you testing on iOS or React Web, if so Touchable is a different component TouchableHighlight, I didn't test. Also if MenuOption is disable, the parameter can't be changed to optionWrapper as it is using style instead if props.

This component is not designed for e2e testing, see #155.

PRs are welcomed :) supporting testID makes sense to me

I work on the e2e PR ;-)
Regarding customStyles not implemented in Touchable as style={customStyles.xxxTouchable} but directly as props is it a bug or ?

thanks @mikbry for PR.

Regarding the question (if I get it right), spreading optionTouchable directly (without style=) was intention so that you can change non-style properties like e.g. underlayColor (see api ). You can always use `optionTouchable={style: {....}} to set the styles.

Yep but I think it should be named customProps instead of customStyle ?

but yes, it is suboptimal name.

For me it is working ok testing 4/5 different MenuOptions. And I checked back at MenuOptions source code:

<Touchable
          onPress={() => this._onSelect()}
          {...defaultTouchableProps}
          {...customStyles.optionTouchable}
        >
          {rendered}
</Touchable>

So optionTouchable is the right parameter. Are you testing on iOS or React Web, if so Touchable is a different component TouchableHighlight, I didn't test. Also if MenuOption is disable, the parameter can't be changed to optionWrapper as it is using style instead if props.

The popup menu works fine on iOS/Android simulators, but I'm trying to use Jest to run tests. I'm trying to use React Native Testing Library such that I can find a MenuOption by it's testID, click on that option, and then test my own code. But fireEvent.press() isn't finding the MenuOption's testID. And when I use Jest's snapshot feature, I can find the testID of MenuTrigger, but I can't find any MenuOption's testID's.

I copied the code that you wrote:
<MenuOption customStyles={{ optionTouchable: { testID: 'option-1' } }} />

@sjmdocto you should test latest version 0.15.10. I added support for testID in MenuOption and MenuTrigger

For me it is working ok testing 4/5 different MenuOptions. And I checked back at MenuOptions source code:

<Touchable
          onPress={() => this._onSelect()}
          {...defaultTouchableProps}
          {...customStyles.optionTouchable}
        >
          {rendered}
</Touchable>

So optionTouchable is the right parameter. Are you testing on iOS or React Web, if so Touchable is a different component TouchableHighlight, I didn't test. Also if MenuOption is disable, the parameter can't be changed to optionWrapper as it is using style instead if props.

The popup menu works fine on iOS/Android simulators, but I'm trying to use Jest to run tests. I'm trying to use React Native Testing Library such that I can find a MenuOption by it's testID, click on that option, and then test my own code. But fireEvent.press() isn't finding the MenuOption's testID. And when I use Jest's snapshot feature, I can find the testID of MenuTrigger, but I can't find any MenuOption's testID's.

I copied the code that you wrote: <MenuOption customStyles={{ optionTouchable: { testID: 'option-1' } }} />

Hey @sjmdocto did you find a solution for this? Exact same use case.

Should also be noted I'm on version 0.15.12 @mikbry - looks like fireEvent.press is causing the menu options to show in the DOM.

Has anyone gotten Jest fireEvent.press() working?

No MenuOption in snapshots, also no elements found by testID of menu option.

const menuOptionStyle = useMemo(
    (): MenuOptionCustomStyle => ({
      optionWrapper: {
        ...style.option,
        ...optionStyle
      },
      OptionTouchableComponent: TouchableOpacity,
      optionTouchable: { testID: 'dropdown-option' }
    }),
    [optionStyle]
  );

  return (
    <MenuOption
      customStyles={menuOptionStyle}
      disabled={isDisabled}
      value={value}
      onSelect={handleSelect}>
      {icon && <View style={[style.icon, iconStyle]}>{icon}</View>}
      <AppText style={titleStyle}>{title}</AppText>
    </MenuOption>
  );

still not working for me using RNTL fireevent.press is not opening my menu @sodik82