How to test in react

Hi there,

I would like to test a simple KT Menu component in react. It seems that the button click event does not apply the "show" class to the menu element in the test as expected. Can you please point me in the right direction on how to test KT Menu components?

Thanks!

Text formatting options
Submit
Here's a how to add some HTML formatting to your comment:
  • <pre></pre> for JS codes block
  • <pre lang="html"></pre> for HTML code block
  • <pre lang="scss"></pre> for SCSS code block
  • <pre lang="php"></pre> for PHP code block
  • <code></code> for single line of code
  • <strong></strong> to make things bold
  • <em></em> to emphasize
  • <ul><li></li></ul>  to make list
  • <ol><li></li></ol>  to make ordered list
  • <h3></h3> to make headings
  • <a></a> for links
  • <img> to paste in an image
  • <blockquote></blockquote> to quote somebody
  • happy  :)
  • shocked  :|
  • sad  :(

Replies (5)

Hi Tamas,

Could you please specify which Metronic version are you using?

We are initializing all kt-menu items using typescript component src/_metronic/assets/ts/components/MenuComponent.ts, make sure that components initialization function is triggered in src/_metronic/layout/MasterInit.tsx.

Here is component usage example.

<a
href='#'
className={clsx('btn btn-sm btn-flex fw-bold', daterangepickerButtonClass)}
data-kt-menu-trigger='click'
data-kt-menu-placement='bottom-end'
>
<KTSVG
path='/media/icons/duotune/general/gen031.svg'
className='svg-icon-6 svg-icon-muted me-1'
/>
Filter
</a>

<div className='menu menu-sub menu-sub-dropdown w-250px w-md-300px' data-kt-menu='true'>
<div className='px-7 py-5'>
<div className='fs-5 text-dark fw-bolder'>Filter Options</div>
</div>

<div className='separator border-gray-200'></div>

<div className='px-7 py-5'>
<div className='mb-10'>
<label className='form-label fw-bold'>Status:</label>

<div>
<select
className='form-select form-select-solid'
data-kt-select2='true'
data-placeholder='Select option'
data-allow-clear='true'
defaultValue={'1'}
>
<option></option>
<option value='1'>Approved</option>
<option value='2'>Pending</option>
<option value='3'>In Process</option>
<option value='4'>Rejected</option>
</select>
</div>
</div>

<div className='mb-10'>
<label className='form-label fw-bold'>Member Type:</label>

<div className='d-flex'>
<label className='form-check form-check-sm form-check-custom form-check-solid me-5'>
<input className='form-check-input' type='checkbox' value='1' />
<span className='form-check-label'>Author</span>
</label>

<label className='form-check form-check-sm form-check-custom form-check-solid'>
<input className='form-check-input' type='checkbox' value='2' defaultChecked={true} />
<span className='form-check-label'>Customer</span>
</label>
</div>
</div>

<div className='mb-10'>
<label className='form-label fw-bold'>Notifications:</label>

<div className='form-check form-switch form-switch-sm form-check-custom form-check-solid'>
<input
className='form-check-input'
type='checkbox'
value=''
name='notifications'
defaultChecked={true}
/>
<label className='form-check-label'>Enabled</label>
</div>
</div>

<div className='d-flex justify-content-end'>
<button
type='reset'
className='btn btn-sm btn-light btn-active-light-primary me-2'
data-kt-menu-dismiss='true'
>
Reset
</button>

<button type='submit' className='btn btn-sm btn-primary' data-kt-menu-dismiss='true'>
Apply
</button>
</div>
</div>
</div>


Regards,
Lauris Stepanovs,
Keenthemes Support Team

Hi Lauris,

I am using the default MasterInit.tsx, and it looks good. I have the latest available version:
REACT_APP_VERSION=v8.1.5

Here is a simple test that fails. In chrome dev-tools, I can see the "show" class being added to the test-menu component on button click.

it('should open menu when button is clicked', () => {
render(<TestFilter />)
const button = screen.getByTestId('filter-button')
userEvent.click(button)
expect(screen.getByTestId('test-menu')).toHaveClass('show')
})

How could this be tested?

Thanks,
Tamas

Hi,

We haven't tried testing components in this way but it seems like this test will only trigger component functions and button will not have events that were initialized in a different component. To fix this you can move menu initialization into your TestFilter component.

Just call MenuComponent.bootstrap().

Regards,
Lauris Stepanovs,
Keenthemes Support Team

Hi Lauris!

Thanks for your reply. I tried to do it like this:

function TestFilter() {
useEffect(() => {
MenuComponent.bootstrap()
}, [])

return (
<div>
<a
href='#'
className={clsx('btn btn-sm btn-flex fw-bold')}
data-kt-menu-trigger='click'
data-kt-menu-placement='bottom-end'
data-testid='filter-button'
>
<KTSVG
path='/media/icons/duotune/general/gen031.svg'
className='svg-icon-6 svg-icon-muted me-1'
/>
Filter
</a>
<div
className='menu menu-sub menu-sub-dropdown w-250px w-md-300px'
data-kt-menu='true'
data-testid='test-menu'
>
<div className='px-7 py-5'>
<div className='fs-5 text-dark fw-bolder'>Filter Options</div>
</div>{' '}
<div className='separator border-gray-200'></div>{' '}
<div className='px-7 py-5'>
<div className='mb-10'>
<label className='form-label fw-bold'>Status:</label>{' '}
<div>
<select
className='form-select form-select-solid'
data-kt-select2='true'
data-placeholder='Select option'
data-allow-clear='true'
defaultValue={'1'}
>
<option></option>
<option value='1'>Approved</option>
<option value='2'>Pending</option>
<option value='3'>In Process</option>
<option value='4'>Rejected</option>
</select>
</div>
</div>{' '}
<div className='mb-10'>
<label className='form-label fw-bold'>Member Type:</label>{' '}
<div className='d-flex'>
<label className='form-check form-check-sm form-check-custom form-check-solid me-5'>
<input className='form-check-input' type='checkbox' value='1' />
<span className='form-check-label'>Author</span>
</label>{' '}
<label className='form-check form-check-sm form-check-custom form-check-solid'>
<input
className='form-check-input'
type='checkbox'
value='2'
defaultChecked={true}
/>
<span className='form-check-label'>Customer</span>
</label>
</div>
</div>{' '}
<div className='mb-10'>
<label className='form-label fw-bold'>Notifications:</label>{' '}
<div className='form-check form-switch form-switch-sm form-check-custom form-check-solid'>
<input
className='form-check-input'
type='checkbox'
value=''
name='notifications'
defaultChecked={true}
/>
<label className='form-check-label'>Enabled</label>
</div>
</div>{' '}
<div className='d-flex justify-content-end'>
<button
type='reset'
className='btn btn-sm btn-light btn-active-light-primary me-2'
data-kt-menu-dismiss='true'
>
Reset
</button>
<button type='submit' className='btn btn-sm btn-primary' data-kt-menu-dismiss='true'>
Apply
</button>
</div>
</div>
</div>
</div>
)
}

export default TestFilter

Still doesn't work. What could be the issue?

Thanks,
Tamas

Hi Tamas,

Unfortunately, we haven't tried to write React component tests at the moment, so we cannot give you a lot of help with this problem.

If this code works inside your browser then the issue is related to specific of your testing library. You can refer to their documentation and check how components are rendered in this context.

Regards,
Lauris Stepanovs,
Keenthemes Support Team

Text formatting options
Submit
Here's a how to add some HTML formatting to your comment:
  • <pre></pre> for JS codes block
  • <pre lang="html"></pre> for HTML code block
  • <pre lang="scss"></pre> for SCSS code block
  • <pre lang="php"></pre> for PHP code block
  • <code></code> for single line of code
  • <strong></strong> to make things bold
  • <em></em> to emphasize
  • <ul><li></li></ul>  to make list
  • <ol><li></li></ol>  to make ordered list
  • <h3></h3> to make headings
  • <a></a> for links
  • <img> to paste in an image
  • <blockquote></blockquote> to quote somebody
  • happy  :)
  • shocked  :|
  • sad  :(
Text formatting options
Submit
Here's a how to add some HTML formatting to your comment:
  • <pre></pre> for JS codes block
  • <pre lang="html"></pre> for HTML code block
  • <pre lang="scss"></pre> for SCSS code block
  • <pre lang="php"></pre> for PHP code block
  • <code></code> for single line of code
  • <strong></strong> to make things bold
  • <em></em> to emphasize
  • <ul><li></li></ul>  to make list
  • <ol><li></li></ol>  to make ordered list
  • <h3></h3> to make headings
  • <a></a> for links
  • <img> to paste in an image
  • <blockquote></blockquote> to quote somebody
  • happy  :)
  • shocked  :|
  • sad  :(