@@ -254,7 +254,10 @@ export async function rawClick(
254
254
let next : HTMLElement | null = element as HTMLElement | null
255
255
while ( next !== null ) {
256
256
if ( next . matches ( focusableSelector ) ) {
257
- next . focus ( )
257
+ act ( ( ) => {
258
+ // act scopes are called immediately. `next` should keep its type refinements.
259
+ next ! . focus ( )
260
+ } )
258
261
break
259
262
}
260
263
next = next . parentElement
@@ -288,37 +291,40 @@ export async function rawClick(
288
291
}
289
292
290
293
export async function focus ( element : Document | Element | Window | Node | null ) {
291
- try {
292
- if ( element === null ) return expect ( element ) . not . toBe ( null )
294
+ await act ( async ( ) => {
295
+ try {
296
+ if ( element === null ) return expect ( element ) . not . toBe ( null )
297
+ if ( element instanceof HTMLElement ) {
298
+ element . focus ( )
299
+ } else {
300
+ fireEvent . focus ( element )
301
+ }
293
302
294
- if ( element instanceof HTMLElement ) {
295
- element . focus ( )
296
- } else {
297
- fireEvent . focus ( element )
303
+ await new Promise ( nextFrame )
304
+ } catch ( err ) {
305
+ if ( err instanceof Error ) Error . captureStackTrace ( err , focus )
306
+ throw err
298
307
}
299
-
300
- await new Promise ( nextFrame )
301
- } catch ( err ) {
302
- if ( err instanceof Error ) Error . captureStackTrace ( err , focus )
303
- throw err
304
- }
308
+ } )
305
309
}
306
310
307
311
export async function blur ( element : Document | Element | Window | Node | null ) {
308
- try {
309
- if ( element === null ) return expect ( element ) . not . toBe ( null )
312
+ await act ( async ( ) => {
313
+ try {
314
+ if ( element === null ) return expect ( element ) . not . toBe ( null )
315
+
316
+ if ( element instanceof HTMLElement ) {
317
+ element . blur ( )
318
+ } else {
319
+ fireEvent . blur ( element )
320
+ }
310
321
311
- if ( element instanceof HTMLElement ) {
312
- element . blur ( )
313
- } else {
314
- fireEvent . blur ( element )
322
+ await new Promise ( nextFrame )
323
+ } catch ( err ) {
324
+ if ( err instanceof Error ) Error . captureStackTrace ( err , blur )
325
+ throw err
315
326
}
316
-
317
- await new Promise ( nextFrame )
318
- } catch ( err ) {
319
- if ( err instanceof Error ) Error . captureStackTrace ( err , blur )
320
- throw err
321
- }
327
+ } )
322
328
}
323
329
324
330
export async function mouseEnter ( element : Document | Element | Window | null ) {
@@ -401,7 +407,10 @@ export async function mouseDrag(
401
407
let next : HTMLElement | null = startingElement as HTMLElement | null
402
408
while ( next !== null ) {
403
409
if ( next . matches ( focusableSelector ) ) {
404
- next . focus ( )
410
+ act ( ( ) => {
411
+ // act scopes are called immediately. `next` should keep its type refinements.
412
+ next ! . focus ( )
413
+ } )
405
414
break
406
415
}
407
416
next = next . parentElement
@@ -455,7 +464,11 @@ function focusNext(event: Partial<KeyboardEvent>) {
455
464
let currentIdx = focusableElements . indexOf ( document . activeElement as HTMLElement )
456
465
let next = focusableElements [ ( currentIdx + total + direction + offset ) % total ] as HTMLElement
457
466
458
- if ( next ) next ?. focus ( { preventScroll : true } )
467
+ if ( next ) {
468
+ act ( ( ) => {
469
+ next ?. focus ( { preventScroll : true } )
470
+ } )
471
+ }
459
472
460
473
if ( next !== document . activeElement ) return innerFocusNext ( offset + direction )
461
474
return next
0 commit comments