Reactstrap Button.Ripple component cause jest test to fail

Hello friends , my app works fine but when running the test I’m getting this Error:


but after replacing the Button.Ripple component with a Button test run without error (the two have different style but same behavior).
code for Login component

import { useSkin } from '@hooks/useSkin'
import { Link, useHistory } from 'react-router-dom'
import InputPasswordToggle from '@components/input-password-toggle'
import { Row, Container, Col, CardText, Form, FormGroup, Label, Input, CustomInput, Button } from 'reactstrap'
import '@styles/base/pages/page-auth.scss'
import sprite from '@src/assets/images/sprite.svg'
import { useRTL } from '@hooks/useRTL'
import { useEffect, useContext} from 'react'
import { useDispatch } from 'react-redux'
import { handleLogin } from '@store/actions/auth/index'
import jwt from '../../../auth/jwt/useJwt'
import SweetAlertTypes from '../../components/sweet-alert/SweetAlertTypes'
import { AbilityContext } from '@src/utility/context/Can'

const currentYear = new Date().getFullYear()
export const Login = () => {
  const [skin, setSkin] = useSkin()
  const [isRtl, setIsRtl] = useRTL()
  const dispatch = useDispatch()
  const history = useHistory()
  const ability = useContext(AbilityContext)

  const formSubmitHandler = async (e) => {
    e.preventDefault()
    const name = document.getElementById('login-email').value
    const password = document.getElementById('login-password').value
    try {
      const res = await jwt.login({
        email: name,
        password
      })
      if (res.status === 200) {
        SweetAlertTypes('success')
        
        if (res.data.role === "admin") {
          ability.update([{action: "manage", ressource: "all"}])
          dispatch(handleLogin({...res.data, ability: [{action: "manage", ressource: "all"}]}))
         } else {
          ability.update([{action: "read", ressource: "home"}])
          dispatch(handleLogin({...res.data, ability: [{action: "read", ressource: "home"}]}))
         }
        window.setTimeout(() => {
          history.push("/home")
        }, 2000)
      }
    } catch (err) {
      SweetAlertTypes('error')
      console.log(err)
    }
  }
  const illustration = skin === 'dark' ? 'login-v2-dark.svg' : 'login-v2.svg',
    source = require(`@src/assets/images/pages/${illustration}`).default
  useEffect(() => {
    setIsRtl(false)
  }, [])
  return (
    <Container className="p-0 m-0 bg-black h-100">
      <Row className='auth-header ml-0'>
        <svg className="auth-header__brand-logo ml-1">
          <use xlinkHref={`${sprite}#icon-balance-scale`}></use>
        </svg>
        <h2 className='auth-header__title'>Avocat <span className='auth-header__title--highlight'>Hassan CHIGRI</span></h2>
        <p className='auth-header__sub-title mb-0'>Cabinet d'avocats</p>
      </Row>
      <h1 className="main-title font-weight-bold text-center mb-0 pt-4">Application Web de Gestion de Cabinet d'Avocat</h1>
    <div className='auth-wrapper auth-v2'>
      <Row className='auth-inner m-0'>
        <Col lg='4' sm='1'></Col>
        <Col className='d-flex align-items-start dark-bg px-2 p-lg-5' lg='4' sm='10'>
          <Col className='px-xl-2 mx-auto' sm='8' md='6' lg='12'>
            <CardText tag='h3' className='font-weight-bold text-center mb-2'>Connectez-Vous</CardText>
            <Form className='auth-login-form mt-2' onSubmit={formSubmitHandler}>
              <FormGroup>
                <Label className='form-label' for='login-email'>
                  Nom
                </Label>
                <Input type='text' id='login-email' placeholder='nom' autoFocus />
              </FormGroup>
              <FormGroup>
                <div className='d-flex justify-content-between'>
                  <Label className='form-label' for='login-password'>
                    Password
                  </Label>
                  <Link to='/'>
                    <small>Forgot Password?</small>
                  </Link>
                </div>
                <InputPasswordToggle placeholder="Mot de passe" className='input-group-merge' id='login-password' />
              </FormGroup>
              <FormGroup>
                <CustomInput type='checkbox' className='custom-control-Primary' id='remember-me' label='Remember Me' />
              </FormGroup>
              <Button.Ripple color='primary' block>
                Sign in
              </Button.Ripple>
            </Form>
            </Col>
        </Col>
        <Col lg='4' sm='1'></Col>
      </Row>
    </div>
    <div className='divider py-2 my-0 mx-3'>
      <div className='divider-text font-weight-bold'> &copy; {currentYear} Tous droits reservés</div>
    </div>
    </Container>
  )
}

export default Login

the code for test-utils:

// test-utils.js
import React from 'react'
import { render as rtlRender } from '@testing-library/react'
import { Provider } from 'react-redux'
// Import your own store
import {store} from '@store/storeConfig/store'
// ** Toast, Int, & ThemeColors Context
import ability from '@src/configs/acl/ability'
import { ThemeContext } from '../context/ThemeColors'
import { IntlProviderWrapper } from '../context/Internationalization'
import { AbilityContext } from '../context/Can'

function render(
  ui,
  {
    ...renderOptions
  } = {},
) {
  function Wrapper({children}) {
    return (
      <Provider store={store}>
      <AbilityContext.Provider value={ability}>
        <ThemeContext>
          <IntlProviderWrapper>
            {children}
          </IntlProviderWrapper>
        </ThemeContext>
      </AbilityContext.Provider>
    </Provider>
    )
  }
  return {
    ...rtlRender(ui, {
      wrapper: Wrapper,
      ...renderOptions,
    }),
    // adding `store` to the returned utilities to allow us
    // to reference it in our tests (just try to avoid using
    // this to test implementation details).
    store,
  }
}

// re-export everything
export * from '@testing-library/react'
// override render method
export { render }

and finally the test:

import { render, screen } from '@src/utility/testsUtils/utils'
import Login from '@src/views/pages/authentication/Login'
import user from '@testing-library/user-event'
import {axe } from 'jest-axe'
import {MemoryRouter} from 'react-router'

describe.only('tesing Login component', () => {
  test('renders login page', async () => {
    render(<MemoryRouter><Login /></MemoryRouter>)
    // debug()
    expect(screen.getByLabelText(/nom/i)).toBeInTheDocument()
  })
})

Thanks in advance for your help :pray: :pray:

Hello there,

I suppose Jest is complaining much the same way I am now:

  • Nowhere in the ReactStrap docs do I see any mention of Button.Ripple
  • I do not see you extending the Button anywhere

hello Sky020,
yes you are right, this is the code that extends Button

// ** Third Party Components
import PropTypes from 'prop-types'
import { Button } from 'reactstrap'
import Ripples from 'react-ripples'

// ** Theme Colors Object
const baseColors = {
  primary: 'rgba(115, 103, 240, .2)',
  secondary: 'rgba(130, 134, 139, .2)',
  success: 'rgba(40, 199, 111, .2)',
  warning: 'rgba(255, 159, 67, .2)',
  danger: 'rgba(234, 84, 85, .2)',
  info: 'rgba(0, 207, 232, .2)',
  dark: 'rgba(30, 30, 30, .2)',
  light: 'rgba(246, 246, 246, .2)'
}

const RippleButton = ({ color, className, during, outline, block, ...rest }) => {
  // ** Return Button Color Based On Variant
  const btnColor = () => {
    if (outline) {
      return baseColors[color]
    } else if (color !== undefined && color.startsWith('flat')) {
      return baseColors[color.substring(5)]
    } else {
      return 'rgba(255, 255, 255, .5)'
    }
  }

  return (
    <Ripples color={btnColor()} during={during} className={`${block ? 'd-block' : ''}`}>
      <Button className={className} color={color} block={block} outline={outline} {...rest} />
    </Ripples>
  )
}

// ** PropTypes
RippleButton.propTypes = {
  ...Button.propTypes,
  rippleColor: PropTypes.string,
  during: PropTypes.number
}

Button.Ripple = RippleButton

I assume this is exported, and within its own file?

it sounds like you need to think about when this code runs, because it does not seem to be running, when your tests do - thus, the component is not extended yet.

1 Like

thanks Sky020 you are right I forgot to import the style in my test file :sweat_smile:.
thanks a lot :pray: :pray: :pray:

1 Like

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.