Adding tests for waitFor util to wait the call back with retry when the callback failed

export const waitFor = async cb => {
  let c = 0
  async function f () {
    console.log('inside f')
    try {
      return await cb()
    } catch (error) {
      if (c < 10) {
        c += 1
        setTimeout(f, 500)
      }
    }
  }
  const result = await f()
  return result
}

I’ve this util to wait my callback, and to retry 10 times in 500ms delay, and want to add a test for waitFor util.

describe('testUtilis', () => {
  it('should wait till callback resolves', async () => {
    const cb = async () => {
      await sleep(500)
      return 'Hello'
    }

    const result = await waitFor(cb)
    expect(result).toBe('Hello')
  })

  it('should retry a failed callback', async () => {
    const globalNow = Date.now()

    const getByText = async () => {
      const now = Date.now()

      const gapInMilliseconds = now - globalNow
      if (gapInMilliseconds <= 2000) throw new Error('less than 2 seconds')

      return 'Hello'
    }

    const result = await waitFor(getByText)
    expect(result).toBe('Hello')
  })
})

I tried to throw an error when the callback is calling for 2 seconds, and to return ‘Hello’ after then, but the callback is calling only one time and the test is failing. What did I overlook here or a different approach for testing the retry part of waitFor.

  it('should upload a pdf on "Upload voucher here" text click', async () => {
    const { getByText } = mountComponent({
      certificate: {
        certificateName: 'Computer science',
        voucherStatus: VOUCHER_STATUS.OUTSTANDING_VOUCHER
      }
    })

    const fileName = 'hello.pdf'

    const file = new File(['"(⌐□_□)"'], fileName, {
      type: 'application/pdf'
    })

    const uploadText = getByText('Upload voucher here')

    fireEvent.change(uploadText, {
      target: {
        files: [file]
      }
    })

    await waitFor(() => {
      expect(getByText('hello.pdf')).toBeInTheDocument()
    })
  })

Test file for fileUpload and it works fine.

{
   selectedFile && (
       <StyledFileName>
          {selectedFile.name}
       </StyledFileName>
   )
}

A snippet in the component, where selectedFile is a state to store the user selected file(event.target.files[0])).