Ganda Rain Panjaitan
Ganda Rain Panjaitan

Reputation: 949

Testing Library React Native

How to check disabled button in formik form with testing library react native? This is my form js. In this form, I have text input will testId input_email, if the email is not valid, the button submit should be disabled.

/* eslint-disable indent */
import * as yup from 'yup'
import { Formik } from 'formik'
import React, { Component, Fragment } from 'react'
import { TextInput, Text, Button, Alert } from 'react-native'
export default class App extends Component {
  render() {
    return (
      <Formik
        initialValues={{ email: '', password: '' }}
        onSubmit={values => Alert.alert(JSON.stringify(values))}
        validationSchema={yup.object().shape({
          email: yup
            .string()
            .email('Enter a valid email')
            .required('Email is required'),
          password: yup
            .string()
            .min(6, 'Password must have at least 6 characters')
            .required('Password is required')
        })}>
        {({
          values,
          handleChange,
          errors,
          setFieldTouched,
          touched,
          isValid,
          handleSubmit
        }) => (
            <Fragment>
              <TextInput
                testID={'input_email'}
                value={values.email}
                onChangeText={handleChange('email')}
                onBlur={() => setFieldTouched('email')}
                placeholder="E-mail"
              />
              {touched.email && errors.email && (
                <Text testID={'error_email'} style={{ fontSize: 10, color: 'red' }}>{errors.email}</Text>
              )}
              <TextInput
                testID={'input_password'}
                value={values.password}
                onChangeText={handleChange('password')}
                placeholder="Password"
                onBlur={() => setFieldTouched('password')}
                secureTextEntry={true}
              />
              {touched.password && errors.password && (
                <Text testID={'error_password'} style={{ fontSize: 10, color: 'red' }}>
                  {errors.password}
                </Text>
              )}
              <Button
                testID={'button_submit'}
                title="Sign In"
                disabled={!isValid}
                onPress={handleSubmit}
              />
            </Fragment>
          )}
      </Formik>
    )
  }
}

This is my test file. In this test file, after fireEvent changeText and blur, will check the value of email input and check the button_submit

/* eslint-disable no-undef */
/**
 * @format
 */

import 'react-native'
import React from 'react'
import renderer from 'react-test-renderer'
import Adapter from 'enzyme-adapter-react-16'
import { shallow, configure } from 'enzyme'
import App from '../App'
import { fireEvent, render, wait, cleanup } from '@testing-library/react-native'

jest.setTimeout(30000)
configure({ adapter: new Adapter(), disableLifecycleMethods: true })
const appWrapper = shallow(<App />)
afterEach(cleanup)

describe('App', () => {
  it('should renders correctly', async () => {
    renderer.create(<App />)
  })

  it('should renders text input email and password', () => {
    expect(appWrapper.find('[id="input_email"]').exists())
    expect(appWrapper.find('[id="input_password"]').exists())
  })

  test('should be show error if value email is not valid', async () => {
    const { getByTestId } = render(<App />)
    const input = getByTestId('input_email')
    fireEvent.changeText(input, 'ganda.com')
    fireEvent.blur(input)
    expect(getByTestId('input_email').props.value).toEqual('ganda.com')
    await wait(() => {
      expect(getByTestId('error_email').props.children).toEqual('Enter a valid email')
      expect(getByTestId('button_submit').props.disabled).toBe(false)
    })
  })
})

But when I run this test file will throw error like this

Expected: false Received: undefined

Upvotes: 1

Views: 1741

Answers (1)

Manuela Viola
Manuela Viola

Reputation: 31

It happened the same to me. To debug I tried:

expect(getByTestId('button_submit').props).toBe(false)

and that showed all the props the button_submit has, and indeed it doesn't contain a disabled prop. In my case it only had style and some build in props, I'm not sure why:

{"accessible": true, "children": [<Text style={{"color": "#FFFFFF", "fontSize": 16, "fontWeight": "600", "lineHeight": 22, "opacity": 0.3}}>Ingresar</Text>, null], "focusable": true, "isTVSelectable": true, "onClick": [Function bound touchableHandlePress], "onResponderGrant": [Function bound touchableHandleResponderGrant], "onResponderMove": [Function bound touchableHandleResponderMove], "onResponderRelease": [Function bound touchableHandleResponderRelease], "onResponderTerminate": [Function bound touchableHandleResponderTerminate], "onResponderTerminationRequest": [Function bound touchableHandleResponderTerminationRequest], "onStartShouldSetResponder": [Function bound touchableHandleStartShouldSetResponder], "style": {"alignItems": "center", "alignSelf": "stretch", "backgroundColor": "rgba(42, 118, 217, 0.3)", "borderColor": "#FFFFFF", "borderRadius": 16, "borderWidth": 0, "justifyContent": "center", "opacity": 1, "padding": 12}, "testID": "login-submit-button"}

Since I have different styling for an enable/disable button I ended up testing the button's style, but I'm still hoping there is a better solution.

expect(submitButton.props.style).toMatchObject({ backgroundColor: 'blue' });

EDIT:

I just found out this exists: https://github.com/testing-library/jest-native

is awesome! And, for example, it contains this:

expect(getByTestId('button')).toBeDisabled();

🥳. 🙌🏼

Upvotes: 2

Related Questions