11
11
12
12
let React ;
13
13
let ReactDOM ;
14
+ let ReactDOMClient ;
14
15
let ReactDOMServer ;
15
16
let ReactTestUtils ;
16
17
18
+ let act ;
19
+
17
20
describe ( 'ReactDOM' , ( ) => {
18
21
beforeEach ( ( ) => {
19
22
jest . resetModules ( ) ;
20
23
React = require ( 'react' ) ;
21
24
ReactDOM = require ( 'react-dom' ) ;
25
+ ReactDOMClient = require ( 'react-dom/client' ) ;
22
26
ReactDOMServer = require ( 'react-dom/server' ) ;
23
27
ReactTestUtils = require ( 'react-dom/test-utils' ) ;
28
+
29
+ act = require ( 'internal-test-utils' ) . act ;
24
30
} ) ;
25
31
26
- it ( 'should bubble onSubmit' , function ( ) {
32
+ it ( 'should bubble onSubmit' , async ( ) => {
27
33
const container = document . createElement ( 'div' ) ;
28
34
29
35
let count = 0 ;
@@ -50,8 +56,11 @@ describe('ReactDOM', () => {
50
56
}
51
57
52
58
document . body . appendChild ( container ) ;
59
+ const root = ReactDOMClient . createRoot ( container ) ;
53
60
try {
54
- ReactDOM . render ( < Parent /> , container ) ;
61
+ await act ( ( ) => {
62
+ root . render ( < Parent /> ) ;
63
+ } ) ;
55
64
buttonRef . click ( ) ;
56
65
expect ( count ) . toBe ( 1 ) ;
57
66
} finally {
@@ -228,7 +237,7 @@ describe('ReactDOM', () => {
228
237
) ;
229
238
} ) ;
230
239
231
- it ( 'preserves focus' , ( ) => {
240
+ it ( 'preserves focus' , async ( ) => {
232
241
let input ;
233
242
let input2 ;
234
243
class A extends React . Component {
@@ -255,8 +264,11 @@ describe('ReactDOM', () => {
255
264
const log = [ ] ;
256
265
const container = document . createElement ( 'div' ) ;
257
266
document . body . appendChild ( container ) ;
267
+ const root = ReactDOMClient . createRoot ( container ) ;
258
268
try {
259
- ReactDOM . render ( < A showTwo = { false } /> , container ) ;
269
+ await act ( ( ) => {
270
+ root . render ( < A showTwo = { false } /> ) ;
271
+ } ) ;
260
272
input . focus ( ) ;
261
273
262
274
// When the second input is added, let's simulate losing focus, which is
@@ -277,7 +289,9 @@ describe('ReactDOM', () => {
277
289
} ) ;
278
290
279
291
expect ( document . activeElement . id ) . toBe ( 'one' ) ;
280
- ReactDOM . render ( < A showTwo = { true } /> , container ) ;
292
+ await act ( ( ) => {
293
+ root . render ( < A showTwo = { true } /> ) ;
294
+ } ) ;
281
295
// input2 gets added, which causes input to get blurred. Then
282
296
// componentDidUpdate focuses input2 and that should make it down to here,
283
297
// not get overwritten by focus restoration.
@@ -288,7 +302,7 @@ describe('ReactDOM', () => {
288
302
}
289
303
} ) ;
290
304
291
- it ( 'calls focus() on autoFocus elements after they have been mounted to the DOM' , ( ) => {
305
+ it ( 'calls focus() on autoFocus elements after they have been mounted to the DOM' , async ( ) => {
292
306
const originalFocus = HTMLElement . prototype . focus ;
293
307
294
308
try {
@@ -305,14 +319,16 @@ describe('ReactDOM', () => {
305
319
306
320
const container = document . createElement ( 'div' ) ;
307
321
document . body . appendChild ( container ) ;
308
- ReactDOM . render (
309
- < div >
310
- < h1 > Auto-focus Test</ h1 >
311
- < input autoFocus = { true } />
312
- < p > The above input should be focused after mount.</ p >
313
- </ div > ,
314
- container ,
315
- ) ;
322
+ const root = ReactDOMClient . createRoot ( container ) ;
323
+ await act ( ( ) => {
324
+ root . render (
325
+ < div >
326
+ < h1 > Auto-focus Test</ h1 >
327
+ < input autoFocus = { true } />
328
+ < p > The above input should be focused after mount.</ p >
329
+ </ div > ,
330
+ ) ;
331
+ } ) ;
316
332
317
333
expect ( inputFocusedAfterMount ) . toBe ( true ) ;
318
334
expect ( focusedElement . tagName ) . toBe ( 'INPUT' ) ;
@@ -321,7 +337,7 @@ describe('ReactDOM', () => {
321
337
}
322
338
} ) ;
323
339
324
- it ( "shouldn't fire duplicate event handler while handling other nested dispatch" , ( ) => {
340
+ it ( "shouldn't fire duplicate event handler while handling other nested dispatch" , async ( ) => {
325
341
const actual = [ ] ;
326
342
327
343
class Wrapper extends React . Component {
@@ -352,8 +368,11 @@ describe('ReactDOM', () => {
352
368
353
369
const container = document . createElement ( 'div' ) ;
354
370
document . body . appendChild ( container ) ;
371
+ const root = ReactDOMClient . createRoot ( container ) ;
355
372
try {
356
- ReactDOM . render ( < Wrapper /> , container ) ;
373
+ await act ( ( ) => {
374
+ root . render ( < Wrapper /> ) ;
375
+ } ) ;
357
376
358
377
const expected = [
359
378
'1st node clicked' ,
@@ -366,7 +385,7 @@ describe('ReactDOM', () => {
366
385
}
367
386
} ) ;
368
387
369
- it ( 'should not crash with devtools installed' , ( ) => {
388
+ it ( 'should not crash with devtools installed' , async ( ) => {
370
389
try {
371
390
global . __REACT_DEVTOOLS_GLOBAL_HOOK__ = {
372
391
inject : function ( ) { } ,
@@ -382,14 +401,17 @@ describe('ReactDOM', () => {
382
401
return < div /> ;
383
402
}
384
403
}
385
- ReactDOM . render ( < Component /> , document . createElement ( 'container' ) ) ;
404
+ const root = ReactDOMClient . createRoot ( document . createElement ( 'div' ) ) ;
405
+ await act ( ( ) => {
406
+ root . render ( < Component /> ) ;
407
+ } ) ;
386
408
} finally {
387
409
delete global . __REACT_DEVTOOLS_GLOBAL_HOOK__ ;
388
410
}
389
411
} ) ;
390
412
391
- it ( 'should not crash calling findDOMNode inside a function component' , ( ) => {
392
- const container = document . createElement ( 'div' ) ;
413
+ it ( 'should not crash calling findDOMNode inside a function component' , async ( ) => {
414
+ const root = ReactDOMClient . createRoot ( document . createElement ( 'div' ) ) ;
393
415
394
416
class Component extends React . Component {
395
417
render ( ) {
@@ -404,11 +426,13 @@ describe('ReactDOM', () => {
404
426
} ;
405
427
406
428
if ( __DEV__ ) {
407
- ReactDOM . render ( < App /> , container ) ;
429
+ await act ( ( ) => {
430
+ root . render ( < App /> ) ;
431
+ } ) ;
408
432
}
409
433
} ) ;
410
434
411
- it ( 'reports stacks with re-entrant renderToString() calls on the client' , ( ) => {
435
+ it ( 'reports stacks with re-entrant renderToString() calls on the client' , async ( ) => {
412
436
function Child2 ( props ) {
413
437
return < span ariaTypo3 = "no" > { props . children } </ span > ;
414
438
}
@@ -441,8 +465,12 @@ describe('ReactDOM', () => {
441
465
) ;
442
466
}
443
467
444
- const container = document . createElement ( 'div' ) ;
445
- expect ( ( ) => ReactDOM . render ( < App /> , container ) ) . toErrorDev ( [
468
+ const root = ReactDOMClient . createRoot ( document . createElement ( 'div' ) ) ;
469
+ await expect ( async ( ) => {
470
+ await act ( ( ) => {
471
+ root . render ( < App /> ) ;
472
+ } ) ;
473
+ } ) . toErrorDev ( [
446
474
// ReactDOM(App > div > span)
447
475
'Invalid ARIA attribute `ariaTypo`. ARIA attributes follow the pattern aria-* and must be lowercase.\n' +
448
476
' in span (at **)\n' +
0 commit comments