How to wait for a session timeout modal to appear in React Testing Library?

67 Views Asked by At

I have a modal that appears in my application after 25 minutes have elapsed while a user is idle. How can I get this modal to appear in Jest?

Here's what I have in my test:

render(<App />);

// Wait 25.5 minutes
setTimeout(() => {}, 1530000);

screen.debug();

Something else I've tried:

jest.useFakeTimers();
jest.advanceTimersByTime(1530000);

render(<App />);

screen.debug();

I'm expecting the modal to appear when debugging the screen, but it does not appear. Any idea how I can accomplish this?

1

There are 1 best solutions below

0
CodeCreater On

Here is one example similar to your scenario:

// MyComponent.jsx
import React, { useState, useEffect } from 'react'
import Modal from 'react-modal'

export const MyComponent = () => {
  const [isIdle, setIsIdle] = useState(false)
  const [modalIsOpen, setModalIsOpen] = useState(false)

  const resetTimer = () => {
    setIsIdle(false)
  }

  useEffect(() => {
    let idleTimer

    const setTimer = () => {
      idleTimer = setTimeout(() => {
        setIsIdle(true)
        setModalIsOpen(true)
      }, 1500000)
    }

    setTimer()

    const resetTimerOnActivity = () => {
      document.addEventListener('mousemove', resetTimer)
      document.addEventListener('keydown', resetTimer)
      document.addEventListener('click', resetTimer)
      document.addEventListener('scroll', resetTimer)
    }

    resetTimerOnActivity()

    return () => {
      clearTimeout(idleTimer)
      document.removeEventListener('mousemove', resetTimer)
      document.removeEventListener('keydown', resetTimer)
      document.removeEventListener('click', resetTimer)
      document.removeEventListener('scroll', resetTimer)
    }
  }, [])

  return (
    <div>
      <h1>Your App</h1>
      {isIdle && (
        <Modal isOpen={modalIsOpen}>
          <div data-testid='modal'>
            <p>You have been idle for 25 minutes.</p>
            <button onClick={() => setModalIsOpen(false)}>Close Modal</button>
          </div>
        </Modal>
      )}
    </div>
  )
}

Above is the code of My Component which opens popup when user stays idle for 25 mins.

Here is my test file

// MyComponent.test.js
import { act, render } from "@testing-library/react"
import React from "react"
import { MyComponent } from "./MyComponent"

describe('My Component', () => {
  it('Should open modal is user remains idle for 25 mins', () => {
    jest.useFakeTimers()
    const { getByTestId } = render(<MyComponent />)
    act(() => {
      jest.advanceTimersByTime(15000000) // advance timer by 25 mins
    })
    expect(getByTestId('modal')).toBeInTheDocument()
  })  
})


Result
enter image description here


Hope it will help!!