(error: Error)
| 196 | } |
| 197 | |
| 198 | async function waitForTasksAndTimers(error: Error) { |
| 199 | do { |
| 200 | // Wait until end of current task/microtask. |
| 201 | await waitForMicrotasks(); |
| 202 | |
| 203 | // $FlowFixMe[cannot-resolve-name]: Flow doesn't know about global Jest object |
| 204 | if (jest.isEnvironmentTornDown()) { |
| 205 | error.message = |
| 206 | 'The Jest environment was torn down before `act` completed. This ' + |
| 207 | 'probably means you forgot to `await` an `act` call.'; |
| 208 | throw error; |
| 209 | } |
| 210 | |
| 211 | // $FlowFixMe[cannot-resolve-name]: Flow doesn't know about global Jest object |
| 212 | const j = jest; |
| 213 | if (j.getTimerCount() > 0) { |
| 214 | // There's a pending timer. Flush it now. We only do this in order to |
| 215 | // force Suspense fallbacks to display; the fact that it's a timer |
| 216 | // is an implementation detail. If there are other timers scheduled, |
| 217 | // those will also fire now, too, which is not ideal. (The public |
| 218 | // version of `act` doesn't do this.) For this reason, we should try |
| 219 | // to avoid using timers in our internal tests. |
| 220 | j.runAllTicks(); |
| 221 | j.runOnlyPendingTimers(); |
| 222 | // If a committing a fallback triggers another update, it might not |
| 223 | // get scheduled until a microtask. So wait one more time. |
| 224 | await waitForMicrotasks(); |
| 225 | } else { |
| 226 | break; |
| 227 | } |
| 228 | } while (true); |
| 229 | } |
| 230 | |
| 231 | export async function serverAct<T>(scope: () => Thenable<T>): Thenable<T> { |
| 232 | // We require every `act` call to assert console logs |
no test coverage detected