Francis
Francis

Reputation: 792

waitFor in react testing-library not entered

I am writing a test for a react component. When I click on the component its content gets hidden. Here is the code of the test:

it('Click to hide minitoc root', async () => {
    const { app } = render(<App />);
    const inThisPage = screen.getByTitle('click here to fold/unfold the mini table of contents')
    const minitocRoot = screen.getByTitle('minitoc root')
    // console.log(inThisPage) // shows <ref *1> HTMLDivElement {...
    // console.log( minitocRoot) // shows <ref *1> HTMLParagraphElement {...
    fireEvent.click(inThisPage)
    console.log('aaaaaa')
    await waitFor(() => {
        ()=> {
              console.log('rrrrrrrrrrrrrrrrrr')  // this never shows 
              expect(getComputedStyle(minitocRoot).display).toBe('none')
             }
        }
      );
      expect(getComputedStyle(minitocRoot).display).toBe('none') // this triggers an error
      console.log('zzzzzz')
 });

It appears the code never enters the waitFor section. The console.log('rrrrrrrrrrrrrrrrrr') never shows up.

inThisPage is a JSX div tag, and minitocRoot is a JSX p tag (verified using console.log)

Here is the JSX code of the component:

        <div
            id='minitoc'
            className={foldedOrNotCSS()}
            style={{ width: widthInPageForToc - 20 }}
        >
            {/* These p tags are hidden, they are like a message board to pass values from React to jQuery */}
            <p id='contentSelector' className='passValueFromReactToJquery'>
                {contentSelector}
            </p>
            <p id='levelsToShow' className='passValueFromReactToJquery'>
                {levelsToShow}
            </p>
            <p id='widthInPageForToc' className='passValueFromReactToJquery'>
                {widthInPageForToc}
            </p>
            <p id='tagsToHideToc' className='passValueFromReactToJquery'>
                {JSON.stringify(tagsToHideToc)}
            </p>

            {/* The "In this page" header of the minitoc, where the user clicks to fold/unfold  */}
            <p
                title='click here to fold/unfold the mini table of contents'
                onClick={handleOpenClose}
                className='inThisPage'
            >
                In this page:{' '}
                <span className='openCloseIcon'>&nbsp;{openCloseIcon()}&nbsp;</span>
            </p>

            {/* This is where the minitoc is going to build  */}
            <div id='minitoc_root' title='minitoc root'></div>
        </div>

Upvotes: 0

Views: 738

Answers (1)

stasdes
stasdes

Reputation: 669

this is working for me:

import { useState } from 'react'

const App = () => {
  const [collapsed, setCollapsed] = useState(false)
  const handleOpenClose = () => {
    console.log('open close')
    setCollapsed(!collapsed)
  }

  return (
    <div id="minitoc">
      <p
        title="click here to fold/unfold the mini table of contents"
        onClick={handleOpenClose}
        className="inThisPage"
      >
        openCloseIcon
      </p>
      <div
        id="minitoc_root"
        title="minitoc root"
        style={{ display: collapsed ? 'none' : 'block' }}
      ></div>
    </div>
  )
}

export default App

import { render, screen, waitFor, fireEvent } from '@testing-library/react'
import App from './MiniTock'

test('renders learn react link', async () => {
  render(<App />)
  const inThisPage = screen.getByTitle('click here to fold/unfold the mini table of contents')
  const minitocRoot = screen.getByTitle('minitoc root')
  expect(getComputedStyle(minitocRoot).display).toBe('block') // this triggers an error
  fireEvent.click(inThisPage)
  await waitFor(() => {
    expect(getComputedStyle(minitocRoot).display).toBe('none')
  })
})

Upvotes: 1

Related Questions