-
Notifications
You must be signed in to change notification settings - Fork 468
Tweak waitFor to not bottleneck async tasks
#1031
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit a4ca576:
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the work. Some lines aren't covered with tests though.
|
@eps1lon Coverage should be good now. |
Codecov Report
@@ Coverage Diff @@
## main #1031 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 25 25
Lines 919 930 +11
Branches 283 287 +4
=========================================
+ Hits 919 930 +11
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
src/__tests__/wait-for.js
Outdated
| await waitFor(async () => { | ||
| currentlyRunningCount++ | ||
| await new Promise(resolve => { | ||
| setTimeout(resolve, 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be greater than interval to illustrate that the callback always completed before another one is started?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test fails as expected when this line is removed 🤷♂️:
dom-testing-library/src/wait-for.js
Line 140 in 45830f5
| if (promiseStatus === 'pending') return |
When using fake timers, we use setTimeout(r, 0) in a while loop, which is why this test works:
dom-testing-library/src/wait-for.js
Line 92 in 45830f5
| setTimeout(r, 0) |
I can still increase the timer if you'd prefer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand how this is related. What are you testing and why is it related to flushing microtasks? My original statement would still apply to real timer usage.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had to add this test to reach 100% testing coverage
dom-testing-library/src/wait-for.js
Line 140 in 45830f5
| if (promiseStatus === 'pending') return |
☝️ this line isn't covered anymore without this test.
I've tweaked the test now, please take another look.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The MutationObserver callback can fire quite often, and if the check is slow/expensive, it can prevent async tasks from being run to completion in a timely manner, ultimately leading to waitFor timing out.
There's currently no test for this. If this change relates to #1031, then you want to do some expensive work in waitFor (e.g. just running a while loop for N milliseconds where N is greater than the interval).
Also "avoid running the next check when the current check is still pending" is already passing on main. I don't see how this test is testing what it says it does.
What: I'm addressing issues with
waitForbottlenecking async tasks and ultimately timing out in some cases. Ref: #820 (comment)Why: The
MutationObservercallback can fire quite often, and if the check is slow/expensive, it can prevent async tasks from being run to completion in a timely manner, ultimately leading towaitFortiming out. Similarly,setIntervalcan queue a new task before the check is complete, so now the "interval" will be between the end of the previous check and the beginning of the next check, instead of between the start of two checks. The "interval" is where async work can actually run, so it's wise to relinquish the main thread to non-test code during that time.How: Added a delay in the
MutationObservercallback, swappedsetIntervalforsetTimeoutChecklist:
docs site
There are 2 non-covered lines now, let me know if you want me to try and add more tests to cover them.