From 8abda5aa992c56b081ab1a90a4337fc58b803703 Mon Sep 17 00:00:00 2001 From: Sebastian Sebbie Silbermann Date: Wed, 12 Nov 2025 12:24:28 +0100 Subject: [PATCH] feat: Use new `waitForWrapper` around `waitFor` scope --- src/__tests__/wait-for.js | 2 +- src/config.ts | 11 ++++++++++- src/wait-for.js | 4 ++-- types/config.d.ts | 2 ++ 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/__tests__/wait-for.js b/src/__tests__/wait-for.js index 38f5b3dd..c750de14 100644 --- a/src/__tests__/wait-for.js +++ b/src/__tests__/wait-for.js @@ -328,7 +328,7 @@ test('does not work after it resolves', async () => { return undefined } }, - asyncWrapper: async callback => { + waitForWrapper: async callback => { contextStack.push('no-act:start') try { await callback() diff --git a/src/config.ts b/src/config.ts index 0168ba88..a651826d 100644 --- a/src/config.ts +++ b/src/config.ts @@ -19,7 +19,16 @@ let config: InternalConfig = { // so we have this config option that's really only intended for // react-testing-library to use. For that reason, this feature will remain // undocumented. - asyncWrapper: cb => cb(), + // Turns out other libraries did use that (user-event). + // Not actually used by DTL but rather by user-event which uses act() from RTL + /* istanbul ignore next */ + asyncWrapper: /* istanbul ignore next */ cb => + /* istanbul ignore next */ cb(), + // For compat with libraries that used asyncWrapper, we add a more specific + // "waitForWrapper" that makes it more clear that this is only meant for waitFor. + // RTL will use this instead to disable act() during that scope while user-event + // can keep relying on the semantics for asyncWrapper. + waitForWrapper: cb => cb(), unstable_advanceTimersWrapper: cb => cb(), eventWrapper: cb => cb(), // default value for the `hidden` option in `ByRole` queries diff --git a/src/wait-for.js b/src/wait-for.js index 4787d031..6a050583 100644 --- a/src/wait-for.js +++ b/src/wait-for.js @@ -184,8 +184,8 @@ function waitForWrapper(callback, options) { // create the error here so its stack trace is as close to the // calling code as possible const stackTraceError = new Error('STACK_TRACE_MESSAGE') - return getConfig().asyncWrapper(() => - waitFor(callback, {stackTraceError, ...options}), + return getConfig().waitForWrapper( + waitFor.bind(null, callback, {stackTraceError, ...options}), ) } diff --git a/types/config.d.ts b/types/config.d.ts index c3617ef0..e390dfa6 100644 --- a/types/config.d.ts +++ b/types/config.d.ts @@ -9,6 +9,8 @@ export interface Config { asyncWrapper(cb: (...args: any[]) => any): Promise // eslint-disable-next-line @typescript-eslint/no-explicit-any eventWrapper(cb: (...args: any[]) => any): void + // eslint-disable-next-line @typescript-eslint/no-explicit-any + waitForWrapper(cb: (...args: any[]) => any): Promise asyncUtilTimeout: number computedStyleSupportsPseudoElements: boolean defaultHidden: boolean