Skip to content

When using fake timers, waitFor still uses a setTimeout with real timers #1176

Closed
@pierrezimmermannbam

Description

@pierrezimmermannbam

Describe the bug

waitFor timeout is using real time when using fake timers, so the fake timers are not necessarily advanced of the timeout. This bug is visible only if the time to perform the check is greater than the interval but it can happen for queries on large components (I met this bug when working on a real codebase).

The following test will fail because the time needed to perform the check is greater than 5ms

test.each([false, true])(
  'it should not depend on real time when using fake timers (legacyFakeTimers = %s)',
  async () => {
    jest.useFakeTimers({ legacyFakeTimers: false });

    const mockErrorFn = jest.fn(() => {
      fibonaci(30);
      throw new Error('test');
    });

    try {
      await waitFor(() => mockErrorFn(), {
        timeout: 200,
        interval: 5,
      });
    } catch (error) {
      // suppress
    }

    expect(mockErrorFn).toHaveBeenCalledTimes(41);
  }
);

Expected behavior

I think this is confusing, as we can't use waitFor in a stable way to advance fake timers and I'd expect than when waitFor fails, the timers have been advanced by its timeout.
However I'm not sure if there is a reason why it was implemented like this, @mdjastrzebski any ideas ?

Steps to Reproduce

The test above fails on the RNTL repo

Screenshots

Versions

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions