Skip to content

unexpected behavior in waitFor #880

Closed
@mlarcher

Description

@mlarcher
  • @testing-library/dom version: 7.29.4
  • Testing Framework and version: Jest 26.6.3 (react-scripts 4.0.1)
  • DOM Environment:
    jsdom@16.4.0
  • node v14.15.4

What you did:

I was investigating random test fails we have on the CI (see testing-library/react-testing-library#848 for details)

What happened:

I noticed that the function I am passing to waitFor was being called even after the timeout occurred.

Suggested solution:

when going through handleTimeout, clearInterval and observer.disconnect() are triggered in the onDone function at https://github.com/testing-library/dom-testing-library/blob/master/src/wait-for.js#L112
Before the call to onDone, there are a few lines of code
https://github.com/testing-library/dom-testing-library/blob/master/src/wait-for.js#L162 that are mostly here to copy the stack trace.
Triggering clearInterval and observer.disconnect() at the beginning of the handleTimeout function makes all the difference between having useless callback invocation after the timeout or not. I suppose that copying the stack trace is long enough to let other calls to the interval sleep through.

Note that in my test case I replaced the setInterval call with a setTimeout calling itself again. When things begin to be dangerously slow, function called with setInterval may run slower than the interval, and begin to run in parallel accumulate in the timers list, slowing things even more...

On a side note, I was debugging using the compiled js version of the code and editing it directly in my node_modules folder. I noticed that the setTimeout/clearTimeout functions were coming from the helper.js file and written as const overallTimeoutTimer = (0, _helpers.setTimeout)(handleTimeout, timeout); while the setInterval/clearInterval weren't. It makes sens to be sure we are not using a mocked timer, but shouldn't it be the case for a setInterval too ? I believe a self calling setTimeout is a better choice in all circumstances, but if there is a good reason to use setInterval instead that I'm not aware of, there may be something fishy there.

In the end those adjustments didn't really help solve my case, but I thought they may be worth sharing.
Also, a quick search before submitting this issue led me to interesting tickets that may or may not be related to the point highlighted above:
#820
#698
#808

Please let me know if those points are worth discussing or if any more info is needed.

(and of course if anyone has any idea of how to investigate further our initial slowdown/timeout, I'd love to hear about it !)

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