简体   繁体   中英

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.

  • If I omit the second expect, the test passes.

  • If I include the second expect, the test fails (expects 'block', not 'none')

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>

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')
  })
})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM