Convert more Scheduler.unstable_flushAll in tests to new test utils (#26369)
`Scheduler.unstable_flushAll` in existing tests doesn't work with microtask. This PR converts most of the remaining `Scheduler.unstable_flushAll()` calls to using internal test utilities to unblock refactoring `ensureRootIsScheduled` with scheduling a microtask.
Tianyu Yao committed
Mar 10, 2023 at 17:56 UTC
432ffc9d0ff2ade0174c76cc23614e0d76963fb1
6 files changed
+332
-270
packages/react-dom/src/events/__tests__/DOMPluginEventSystem-test.internal.js
+159
-117
@@ -80,11 +80,11 @@ describe('DOMPluginEventSystem', () => {
80
ReactDOMClient = require('react-dom/client');
81
Scheduler = require('scheduler');
82
ReactDOMServer = require('react-dom/server');
83
- act = require('internal-test-utils').act;
83
84
const InternalTestUtils = require('internal-test-utils');
85
waitForAll = InternalTestUtils.waitForAll;
86
waitFor = InternalTestUtils.waitFor;
87
+ act = InternalTestUtils.act;
88
89
container = document.createElement('div');
90
document.body.appendChild(container);
@@ -635,8 +635,9 @@ describe('DOMPluginEventSystem', () => {
635
// We're going to use a different root as a parent.
636
// This lets us detect whether an event goes through React's event system.
637
const parentRoot = ReactDOMClient.createRoot(parentContainer);
638
- parentRoot.render(<Parent />);
639
- Scheduler.unstable_flushAll();
638
+ await act(() => {
639
+ parentRoot.render(<Parent />);
640
+ });
641
642
childSlotRef.current.appendChild(childContainer);
643
@@ -647,9 +648,9 @@ describe('DOMPluginEventSystem', () => {
648
suspend = true;
649
650
// Hydrate asynchronously.
650
- ReactDOMClient.hydrateRoot(childContainer, <App />);
651
- jest.runAllTimers();
652
- Scheduler.unstable_flushAll();
651
+ await act(() => {
652
+ ReactDOMClient.hydrateRoot(childContainer, <App />);
653
+ });
654
655
// The Suspense boundary is not yet hydrated.
656
await act(() => {
@@ -1305,7 +1306,7 @@ describe('DOMPluginEventSystem', () => {
1306
});
1307
1308
// @gate www
1308
- it('can render correctly with the ReactDOMServer hydration', () => {
1309
+ it('can render correctly with the ReactDOMServer hydration', async () => {
1310
const clickEvent = jest.fn();
1311
const spanRef = React.createRef();
1312
const setClick = ReactDOM.unstable_createEventHandle('click');
@@ -1324,14 +1325,15 @@ describe('DOMPluginEventSystem', () => {
1325
const output = ReactDOMServer.renderToString(<Test />);
1326
expect(output).toBe(`<div><span>Hello world</span></div>`);
1327
container.innerHTML = output;
1327
- ReactDOM.hydrate(<Test />, container);
1328
- Scheduler.unstable_flushAll();
1328
+ await act(() => {
1329
+ ReactDOM.hydrate(<Test />, container);
1330
+ });
1331
dispatchClickEvent(spanRef.current);
1332
expect(clickEvent).toHaveBeenCalledTimes(1);
1333
});
1334
1335
// @gate www
1334
- it('should correctly work for a basic "click" listener', () => {
1336
+ it('should correctly work for a basic "click" listener', async () => {
1337
let log = [];
1338
const clickEvent = jest.fn(event => {
1339
log.push({
@@ -1357,8 +1359,9 @@ describe('DOMPluginEventSystem', () => {
1359
);
1360
}
1361
1360
- ReactDOM.render(<Test />, container);
1361
- Scheduler.unstable_flushAll();
1362
+ await act(() => {
1363
+ ReactDOM.render(<Test />, container);
1364
+ });
1365
1366
expect(container.innerHTML).toBe(
1367
'<button><div>Click me!</div></button>',
@@ -1378,15 +1381,17 @@ describe('DOMPluginEventSystem', () => {
1381
expect(clickEvent).toBeCalledTimes(1);
1382
1383
// Unmounting the container and clicking should not work
1381
- ReactDOM.render(null, container);
1382
- Scheduler.unstable_flushAll();
1384
+ await act(() => {
1385
+ ReactDOM.render(null, container);
1386
+ });
1387
1388
dispatchClickEvent(divElement);
1389
expect(clickEvent).toBeCalledTimes(1);
1390
1391
// Re-rendering the container and clicking should work
1388
- ReactDOM.render(<Test />, container);
1389
- Scheduler.unstable_flushAll();
1392
+ await act(() => {
1393
+ ReactDOM.render(<Test />, container);
1394
+ });
1395
1396
divElement = divRef.current;
1397
dispatchClickEvent(divElement);
@@ -1421,8 +1426,9 @@ describe('DOMPluginEventSystem', () => {
1426
}
1427
1428
let clickEvent2 = jest.fn();
1424
- ReactDOM.render(<Test2 clickEvent2={clickEvent2} />, container);
1425
- Scheduler.unstable_flushAll();
1429
+ await act(() => {
1430
+ ReactDOM.render(<Test2 clickEvent2={clickEvent2} />, container);
1431
+ });
1432
1433
divElement = divRef.current;
1434
dispatchClickEvent(divElement);
@@ -1430,8 +1436,9 @@ describe('DOMPluginEventSystem', () => {
1436
1437
// Reset the function we pass in, so it's different
1438
clickEvent2 = jest.fn();
1433
- ReactDOM.render(<Test2 clickEvent2={clickEvent2} />, container);
1434
- Scheduler.unstable_flushAll();
1439
+ await act(() => {
1440
+ ReactDOM.render(<Test2 clickEvent2={clickEvent2} />, container);
1441
+ });
1442
1443
divElement = divRef.current;
1444
dispatchClickEvent(divElement);
@@ -1439,7 +1446,7 @@ describe('DOMPluginEventSystem', () => {
1446
});
1447
1448
// @gate www
1442
- it('should correctly work for setting and clearing a basic "click" listener', () => {
1449
+ it('should correctly work for setting and clearing a basic "click" listener', async () => {
1450
const clickEvent = jest.fn();
1451
const divRef = React.createRef();
1452
const buttonRef = React.createRef();
@@ -1461,16 +1468,18 @@ describe('DOMPluginEventSystem', () => {
1468
);
1469
}
1470
1464
- ReactDOM.render(<Test off={false} />, container);
1465
- Scheduler.unstable_flushAll();
1471
+ await act(() => {
1472
+ ReactDOM.render(<Test off={false} />, container);
1473
+ });
1474
1475
let divElement = divRef.current;
1476
dispatchClickEvent(divElement);
1477
expect(clickEvent).toBeCalledTimes(1);
1478
1479
// The listener should get unmounted
1472
- ReactDOM.render(<Test off={true} />, container);
1473
- Scheduler.unstable_flushAll();
1480
+ await act(() => {
1481
+ ReactDOM.render(<Test off={true} />, container);
1482
+ });
1483
1484
clickEvent.mockClear();
1485
@@ -1480,7 +1489,7 @@ describe('DOMPluginEventSystem', () => {
1489
});
1490
1491
// @gate www
1483
- it('should handle the target being a text node', () => {
1492
+ it('should handle the target being a text node', async () => {
1493
const clickEvent = jest.fn();
1494
const buttonRef = React.createRef();
1495
const setClick = ReactDOM.unstable_createEventHandle('click');
@@ -1493,8 +1502,9 @@ describe('DOMPluginEventSystem', () => {
1502
return <button ref={buttonRef}>Click me!</button>;
1503
}
1504
1496
- ReactDOM.render(<Test />, container);
1497
- Scheduler.unstable_flushAll();
1505
+ await act(() => {
1506
+ ReactDOM.render(<Test />, container);
1507
+ });
1508
1509
const textNode = buttonRef.current.firstChild;
1510
dispatchClickEvent(textNode);
@@ -1502,7 +1512,7 @@ describe('DOMPluginEventSystem', () => {
1512
});
1513
1514
// @gate www
1505
- it('handle propagation of click events', () => {
1515
+ it('handle propagation of click events', async () => {
1516
const buttonRef = React.createRef();
1517
const divRef = React.createRef();
1518
const log = [];
@@ -1546,8 +1556,9 @@ describe('DOMPluginEventSystem', () => {
1556
);
1557
}
1558
1549
- ReactDOM.render(<Test />, container);
1550
- Scheduler.unstable_flushAll();
1559
+ await act(() => {
1560
+ ReactDOM.render(<Test />, container);
1561
+ });
1562
1563
const buttonElement = buttonRef.current;
1564
dispatchClickEvent(buttonElement);
@@ -1571,7 +1582,7 @@ describe('DOMPluginEventSystem', () => {
1582
});
1583
1584
// @gate www
1574
- it('handle propagation of click events mixed with onClick events', () => {
1585
+ it('handle propagation of click events mixed with onClick events', async () => {
1586
const buttonRef = React.createRef();
1587
const divRef = React.createRef();
1588
const log = [];
@@ -1610,8 +1621,9 @@ describe('DOMPluginEventSystem', () => {
1621
);
1622
}
1623
1613
- ReactDOM.render(<Test />, container);
1614
- Scheduler.unstable_flushAll();
1624
+ await act(() => {
1625
+ ReactDOM.render(<Test />, container);
1626
+ });
1627
1628
const buttonElement = buttonRef.current;
1629
dispatchClickEvent(buttonElement);
@@ -1631,7 +1643,7 @@ describe('DOMPluginEventSystem', () => {
1643
});
1644
1645
// @gate www
1634
- it('should correctly work for a basic "click" listener on the outer target', () => {
1646
+ it('should correctly work for a basic "click" listener on the outer target', async () => {
1647
const log = [];
1648
const clickEvent = jest.fn(event => {
1649
log.push({
@@ -1657,8 +1669,9 @@ describe('DOMPluginEventSystem', () => {
1669
);
1670
}
1671
1660
- ReactDOM.render(<Test />, container);
1661
- Scheduler.unstable_flushAll();
1672
+ await act(() => {
1673
+ ReactDOM.render(<Test />, container);
1674
+ });
1675
1676
expect(container.innerHTML).toBe(
1677
'<button><div>Click me!</div></button>',
@@ -1682,8 +1695,9 @@ describe('DOMPluginEventSystem', () => {
1695
expect(clickEvent).toBeCalledTimes(1);
1696
1697
// Re-rendering the container and clicking should work
1685
- ReactDOM.render(<Test />, container);
1686
- Scheduler.unstable_flushAll();
1698
+ await act(() => {
1699
+ ReactDOM.render(<Test />, container);
1700
+ });
1701
1702
divElement = divRef.current;
1703
dispatchClickEvent(divElement);
@@ -1696,7 +1710,7 @@ describe('DOMPluginEventSystem', () => {
1710
});
1711
1712
// @gate www
1699
- it('should correctly handle many nested target listeners', () => {
1713
+ it('should correctly handle many nested target listeners', async () => {
1714
const buttonRef = React.createRef();
1715
const targetListener1 = jest.fn();
1716
const targetListener2 = jest.fn();
@@ -1741,8 +1755,9 @@ describe('DOMPluginEventSystem', () => {
1755
return <button ref={buttonRef}>Click me!</button>;
1756
}
1757
1744
- ReactDOM.render(<Test />, container);
1745
- Scheduler.unstable_flushAll();
1758
+ await act(() => {
1759
+ ReactDOM.render(<Test />, container);
1760
+ });
1761
1762
let buttonElement = buttonRef.current;
1763
dispatchClickEvent(buttonElement);
@@ -1787,8 +1802,9 @@ describe('DOMPluginEventSystem', () => {
1802
return <button ref={buttonRef}>Click me!</button>;
1803
}
1804
1790
- ReactDOM.render(<Test2 />, container);
1791
- Scheduler.unstable_flushAll();
1805
+ await act(() => {
1806
+ ReactDOM.render(<Test2 />, container);
1807
+ });
1808
1809
buttonElement = buttonRef.current;
1810
dispatchClickEvent(buttonElement);
@@ -1799,7 +1815,7 @@ describe('DOMPluginEventSystem', () => {
1815
});
1816
1817
// @gate www
1802
- it('should correctly handle stopPropagation correctly for target events', () => {
1818
+ it('should correctly handle stopPropagation correctly for target events', async () => {
1819
const buttonRef = React.createRef();
1820
const divRef = React.createRef();
1821
const clickEvent = jest.fn();
@@ -1828,8 +1844,9 @@ describe('DOMPluginEventSystem', () => {
1844
);
1845
}
1846
1831
- ReactDOM.render(<Test />, container);
1832
- Scheduler.unstable_flushAll();
1847
+ await act(() => {
1848
+ ReactDOM.render(<Test />, container);
1849
+ });
1850
1851
const divElement = divRef.current;
1852
dispatchClickEvent(divElement);
@@ -1837,7 +1854,7 @@ describe('DOMPluginEventSystem', () => {
1854
});
1855
1856
// @gate www
1840
- it('should correctly handle stopPropagation correctly for many target events', () => {
1857
+ it('should correctly handle stopPropagation correctly for many target events', async () => {
1858
const buttonRef = React.createRef();
1859
const targetListener1 = jest.fn(e => e.stopPropagation());
1860
const targetListener2 = jest.fn(e => e.stopPropagation());
@@ -1878,8 +1895,9 @@ describe('DOMPluginEventSystem', () => {
1895
return <button ref={buttonRef}>Click me!</button>;
1896
}
1897
1881
- ReactDOM.render(<Test />, container);
1882
- Scheduler.unstable_flushAll();
1898
+ await act(() => {
1899
+ ReactDOM.render(<Test />, container);
1900
+ });
1901
1902
const buttonElement = buttonRef.current;
1903
dispatchClickEvent(buttonElement);
@@ -1890,7 +1908,7 @@ describe('DOMPluginEventSystem', () => {
1908
});
1909
1910
// @gate www
1893
- it('should correctly handle stopPropagation for mixed capture/bubbling target listeners', () => {
1911
+ it('should correctly handle stopPropagation for mixed capture/bubbling target listeners', async () => {
1912
const buttonRef = React.createRef();
1913
const targetListener1 = jest.fn(e => e.stopPropagation());
1914
const targetListener2 = jest.fn(e => e.stopPropagation());
@@ -1935,8 +1953,9 @@ describe('DOMPluginEventSystem', () => {
1953
return <button ref={buttonRef}>Click me!</button>;
1954
}
1955
1938
- ReactDOM.render(<Test />, container);
1939
- Scheduler.unstable_flushAll();
1956
+ await act(() => {
1957
+ ReactDOM.render(<Test />, container);
1958
+ });
1959
1960
const buttonElement = buttonRef.current;
1961
dispatchClickEvent(buttonElement);
@@ -1996,7 +2015,7 @@ describe('DOMPluginEventSystem', () => {
2015
});
2016
2017
// @gate www
1999
- it('should correctly work for a basic "click" window listener', () => {
2018
+ it('should correctly work for a basic "click" window listener', async () => {
2019
const log = [];
2020
const clickEvent = jest.fn(event => {
2021
log.push({
@@ -2015,8 +2034,9 @@ describe('DOMPluginEventSystem', () => {
2034
2035
return <button>Click anything!</button>;
2036
}
2018
- ReactDOM.render(<Test />, container);
2019
- Scheduler.unstable_flushAll();
2037
+ await act(() => {
2038
+ ReactDOM.render(<Test />, container);
2039
+ });
2040
2041
expect(container.innerHTML).toBe(
2042
'<button>Click anything!</button>',
@@ -2032,22 +2052,24 @@ describe('DOMPluginEventSystem', () => {
2052
});
2053
2054
// Unmounting the container and clicking should not work
2035
- ReactDOM.render(null, container);
2036
- Scheduler.unstable_flushAll();
2055
+ await act(() => {
2056
+ ReactDOM.render(null, container);
2057
+ });
2058
2059
dispatchClickEvent(document.body);
2060
expect(clickEvent).toBeCalledTimes(1);
2061
2062
// Re-rendering and clicking the body should work again
2042
- ReactDOM.render(<Test />, container);
2043
- Scheduler.unstable_flushAll();
2063
+ await act(() => {
2064
+ ReactDOM.render(<Test />, container);
2065
+ });
2066
2067
dispatchClickEvent(document.body);
2068
expect(clickEvent).toBeCalledTimes(2);
2069
});
2070
2071
// @gate www
2050
- it('handle propagation of click events on the window', () => {
2072
+ it('handle propagation of click events on the window', async () => {
2073
const buttonRef = React.createRef();
2074
const divRef = React.createRef();
2075
const log = [];
@@ -2098,8 +2120,9 @@ describe('DOMPluginEventSystem', () => {
2120
);
2121
}
2122
2101
- ReactDOM.render(<Test />, container);
2102
- Scheduler.unstable_flushAll();
2123
+ await act(() => {
2124
+ ReactDOM.render(<Test />, container);
2125
+ });
2126
2127
const buttonElement = buttonRef.current;
2128
dispatchClickEvent(buttonElement);
@@ -2127,7 +2150,7 @@ describe('DOMPluginEventSystem', () => {
2150
});
2151
2152
// @gate www
2130
- it('should correctly handle stopPropagation for mixed listeners', () => {
2153
+ it('should correctly handle stopPropagation for mixed listeners', async () => {
2154
const buttonRef = React.createRef();
2155
const rootListener1 = jest.fn(e => e.stopPropagation());
2156
const rootListener2 = jest.fn();
@@ -2166,8 +2189,9 @@ describe('DOMPluginEventSystem', () => {
2189
return <button ref={buttonRef}>Click me!</button>;
2190
}
2191
2169
- ReactDOM.render(<Test />, container);
2170
- Scheduler.unstable_flushAll();
2192
+ await act(() => {
2193
+ ReactDOM.render(<Test />, container);
2194
+ });
2195
2196
const buttonElement = buttonRef.current;
2197
dispatchClickEvent(buttonElement);
@@ -2178,7 +2202,7 @@ describe('DOMPluginEventSystem', () => {
2202
});
2203
2204
// @gate www
2181
- it('should correctly handle stopPropagation for delegated listeners', () => {
2205
+ it('should correctly handle stopPropagation for delegated listeners', async () => {
2206
const buttonRef = React.createRef();
2207
const rootListener1 = jest.fn(e => e.stopPropagation());
2208
const rootListener2 = jest.fn();
@@ -2211,9 +2235,9 @@ describe('DOMPluginEventSystem', () => {
2235
return <button ref={buttonRef}>Click me!</button>;
2236
}
2237
2214
- ReactDOM.render(<Test />, container);
2215
-
2216
- Scheduler.unstable_flushAll();
2238
+ await act(() => {
2239
+ ReactDOM.render(<Test />, container);
2240
+ });
2241
2242
const buttonElement = buttonRef.current;
2243
dispatchClickEvent(buttonElement);
@@ -2224,7 +2248,7 @@ describe('DOMPluginEventSystem', () => {
2248
});
2249
2250
// @gate www
2227
- it('handle propagation of click events on the window and document', () => {
2251
+ it('handle propagation of click events on the window and document', async () => {
2252
const buttonRef = React.createRef();
2253
const divRef = React.createRef();
2254
const log = [];
@@ -2282,8 +2306,9 @@ describe('DOMPluginEventSystem', () => {
2306
);
2307
}
2308
2285
- ReactDOM.render(<Test />, container);
2286
- Scheduler.unstable_flushAll();
2309
+ await act(() => {
2310
+ ReactDOM.render(<Test />, container);
2311
+ });
2312
2313
const buttonElement = buttonRef.current;
2314
dispatchClickEvent(buttonElement);
@@ -2349,7 +2374,7 @@ describe('DOMPluginEventSystem', () => {
2374
});
2375
2376
// @gate www
2352
- it('beforeblur and afterblur are called after a focused element is unmounted', () => {
2377
+ it('beforeblur and afterblur are called after a focused element is unmounted', async () => {
2378
const log = [];
2379
// We have to persist here because we want to read relatedTarget later.
2380
const onAfterBlur = jest.fn(e => {
@@ -2385,8 +2410,9 @@ describe('DOMPluginEventSystem', () => {
2410
);
2411
};
2412
2388
- ReactDOM.render(<Component show={true} />, container);
2389
- Scheduler.unstable_flushAll();
2413
+ await act(() => {
2414
+ ReactDOM.render(<Component show={true} />, container);
2415
+ });
2416
2417
const inner = innerRef.current;
2418
const target = createEventTarget(inner);
@@ -2394,8 +2420,9 @@ describe('DOMPluginEventSystem', () => {
2420
expect(onBeforeBlur).toHaveBeenCalledTimes(0);
2421
expect(onAfterBlur).toHaveBeenCalledTimes(0);
2422
2397
- ReactDOM.render(<Component show={false} />, container);
2398
- Scheduler.unstable_flushAll();
2423
+ await act(() => {
2424
+ ReactDOM.render(<Component show={false} />, container);
2425
+ });
2426
2427
expect(onBeforeBlur).toHaveBeenCalledTimes(1);
2428
expect(onAfterBlur).toHaveBeenCalledTimes(1);
@@ -2406,7 +2433,7 @@ describe('DOMPluginEventSystem', () => {
2433
});
2434
2435
// @gate www
2409
- it('beforeblur and afterblur are called after a nested focused element is unmounted', () => {
2436
+ it('beforeblur and afterblur are called after a nested focused element is unmounted', async () => {
2437
const log = [];
2438
// We have to persist here because we want to read relatedTarget later.
2439
const onAfterBlur = jest.fn(e => {
@@ -2446,8 +2473,9 @@ describe('DOMPluginEventSystem', () => {
2473
);
2474
};
2475
2449
- ReactDOM.render(<Component show={true} />, container);
2450
- Scheduler.unstable_flushAll();
2476
+ await act(() => {
2477
+ ReactDOM.render(<Component show={true} />, container);
2478
+ });
2479
2480
const inner = innerRef.current;
2481
const target = createEventTarget(inner);
@@ -2455,8 +2483,9 @@ describe('DOMPluginEventSystem', () => {
2483
expect(onBeforeBlur).toHaveBeenCalledTimes(0);
2484
expect(onAfterBlur).toHaveBeenCalledTimes(0);
2485
2458
- ReactDOM.render(<Component show={false} />, container);
2459
- Scheduler.unstable_flushAll();
2486
+ await act(() => {
2487
+ ReactDOM.render(<Component show={false} />, container);
2488
+ });
2489
2490
expect(onBeforeBlur).toHaveBeenCalledTimes(1);
2491
expect(onAfterBlur).toHaveBeenCalledTimes(1);
@@ -2467,7 +2496,7 @@ describe('DOMPluginEventSystem', () => {
2496
});
2497
2498
// @gate www
2470
- it('beforeblur should skip handlers from a deleted subtree after the focused element is unmounted', () => {
2499
+ it('beforeblur should skip handlers from a deleted subtree after the focused element is unmounted', async () => {
2500
const onBeforeBlur = jest.fn();
2501
const innerRef = React.createRef();
2502
const innerRef2 = React.createRef();
@@ -2505,16 +2534,18 @@ describe('DOMPluginEventSystem', () => {
2534
);
2535
};
2536
2508
- ReactDOM.render(<Component show={true} />, container);
2509
- Scheduler.unstable_flushAll();
2537
+ await act(() => {
2538
+ ReactDOM.render(<Component show={true} />, container);
2539
+ });
2540
2541
const inner = innerRef.current;
2542
const target = createEventTarget(inner);
2543
target.focus();
2544
expect(onBeforeBlur).toHaveBeenCalledTimes(0);
2545
2516
- ReactDOM.render(<Component show={false} />, container);
2517
- Scheduler.unstable_flushAll();
2546
+ await act(() => {
2547
+ ReactDOM.render(<Component show={false} />, container);
2548
+ });
2549
2550
expect(onBeforeBlur).toHaveBeenCalledTimes(1);
2551
});
@@ -2745,7 +2776,7 @@ describe('DOMPluginEventSystem', () => {
2776
});
2777
2778
// @gate www
2748
- it('handle propagation of click events between disjointed comment roots', () => {
2779
+ it('handle propagation of click events between disjointed comment roots', async () => {
2780
const buttonRef = React.createRef();
2781
const divRef = React.createRef();
2782
const log = [];
@@ -2792,11 +2823,13 @@ describe('DOMPluginEventSystem', () => {
2823
const disjointedNode = document.createComment(
2824
' react-mount-point-unstable ',
2825
);
2795
- ReactDOM.render(<Parent />, container);
2796
- Scheduler.unstable_flushAll();
2826
+ await act(() => {
2827
+ ReactDOM.render(<Parent />, container);
2828
+ });
2829
buttonRef.current.appendChild(disjointedNode);
2798
- ReactDOM.render(<Child />, disjointedNode);
2799
- Scheduler.unstable_flushAll();
2830
+ await act(() => {
2831
+ ReactDOM.render(<Child />, disjointedNode);
2832
+ });
2833
2834
const buttonElement = buttonRef.current;
2835
dispatchClickEvent(buttonElement);
@@ -2816,7 +2849,7 @@ describe('DOMPluginEventSystem', () => {
2849
});
2850
2851
// @gate www
2819
- it('propagates known createEventHandle events through portals without inner listeners', () => {
2852
+ it('propagates known createEventHandle events through portals without inner listeners', async () => {
2853
const buttonRef = React.createRef();
2854
const divRef = React.createRef();
2855
const log = [];
@@ -2859,8 +2892,9 @@ describe('DOMPluginEventSystem', () => {
2892
);
2893
}
2894
2862
- ReactDOM.render(<Parent />, container);
2863
- Scheduler.unstable_flushAll();
2895
+ await act(() => {
2896
+ ReactDOM.render(<Parent />, container);
2897
+ });
2898
2899
const divElement = divRef.current;
2900
const buttonElement = buttonRef.current;
@@ -2885,10 +2919,11 @@ describe('DOMPluginEventSystem', () => {
2919
ReactDOMClient = require('react-dom/client');
2920
Scheduler = require('scheduler');
2921
ReactDOMServer = require('react-dom/server');
2922
+ act = require('internal-test-utils').act;
2923
});
2924
2925
// @gate www
2891
- it('handle propagation of click events on a scope', () => {
2926
+ it('handle propagation of click events on a scope', async () => {
2927
const buttonRef = React.createRef();
2928
const log = [];
2929
const onClick = jest.fn(e =>
@@ -2929,8 +2964,9 @@ describe('DOMPluginEventSystem', () => {
2964
);
2965
}
2966
2932
- ReactDOM.render(<Test />, container);
2933
- Scheduler.unstable_flushAll();
2967
+ await act(() => {
2968
+ ReactDOM.render(<Test />, container);
2969
+ });
2970
2971
const buttonElement = buttonRef.current;
2972
dispatchClickEvent(buttonElement);
@@ -2944,7 +2980,7 @@ describe('DOMPluginEventSystem', () => {
2980
});
2981
2982
// @gate www
2947
- it('handle mixed propagation of click events on a scope', () => {
2983
+ it('handle mixed propagation of click events on a scope', async () => {
2984
const buttonRef = React.createRef();
2985
const divRef = React.createRef();
2986
const log = [];
@@ -3000,8 +3036,9 @@ describe('DOMPluginEventSystem', () => {
3036
);
3037
}
3038
3003
- ReactDOM.render(<Test />, container);
3004
- Scheduler.unstable_flushAll();
3039
+ await act(() => {
3040
+ ReactDOM.render(<Test />, container);
3041
+ });
3042
3043
const buttonElement = buttonRef.current;
3044
dispatchClickEvent(buttonElement);
@@ -3035,7 +3072,7 @@ describe('DOMPluginEventSystem', () => {
3072
});
3073
3074
// @gate www
3038
- it('should not handle the target being a dangling text node within a scope', () => {
3075
+ it('should not handle the target being a dangling text node within a scope', async () => {
3076
const clickEvent = jest.fn();
3077
const buttonRef = React.createRef();
3078
const TestScope = React.unstable_Scope;
@@ -3055,8 +3092,9 @@ describe('DOMPluginEventSystem', () => {
3092
);
3093
}
3094
3058
- ReactDOM.render(<Test />, container);
3059
- Scheduler.unstable_flushAll();
3095
+ await act(() => {
3096
+ ReactDOM.render(<Test />, container);
3097
+ });
3098
3099
const textNode = buttonRef.current.firstChild;
3100
dispatchClickEvent(textNode);
@@ -3066,7 +3104,7 @@ describe('DOMPluginEventSystem', () => {
3104
});
3105
3106
// @gate www
3069
- it('handle stopPropagation (inner) correctly between scopes', () => {
3107
+ it('handle stopPropagation (inner) correctly between scopes', async () => {
3108
const buttonRef = React.createRef();
3109
const outerOnClick = jest.fn();
3110
const innerOnClick = jest.fn(e => e.stopPropagation());
@@ -3097,8 +3135,9 @@ describe('DOMPluginEventSystem', () => {
3135
);
3136
}
3137
3100
- ReactDOM.render(<Test />, container);
3101
- Scheduler.unstable_flushAll();
3138
+ await act(() => {
3139
+ ReactDOM.render(<Test />, container);
3140
+ });
3141
3142
const buttonElement = buttonRef.current;
3143
dispatchClickEvent(buttonElement);
@@ -3108,7 +3147,7 @@ describe('DOMPluginEventSystem', () => {
3147
});
3148
3149
// @gate www
3111
- it('handle stopPropagation (outer) correctly between scopes', () => {
3150
+ it('handle stopPropagation (outer) correctly between scopes', async () => {
3151
const buttonRef = React.createRef();
3152
const outerOnClick = jest.fn(e => e.stopPropagation());
3153
const innerOnClick = jest.fn();
@@ -3139,8 +3178,9 @@ describe('DOMPluginEventSystem', () => {
3178
);
3179
}
3180
3142
- ReactDOM.render(<Test />, container);
3143
- Scheduler.unstable_flushAll();
3181
+ await act(() => {
3182
+ ReactDOM.render(<Test />, container);
3183
+ });
3184
3185
const buttonElement = buttonRef.current;
3186
dispatchClickEvent(buttonElement);
@@ -3150,7 +3190,7 @@ describe('DOMPluginEventSystem', () => {
3190
});
3191
3192
// @gate www
3153
- it('handle stopPropagation (inner and outer) correctly between scopes', () => {
3193
+ it('handle stopPropagation (inner and outer) correctly between scopes', async () => {
3194
const buttonRef = React.createRef();
3195
const onClick = jest.fn(e => e.stopPropagation());
3196
const TestScope = React.unstable_Scope;
@@ -3180,8 +3220,9 @@ describe('DOMPluginEventSystem', () => {
3220
);
3221
}
3222
3183
- ReactDOM.render(<Test />, container);
3184
- Scheduler.unstable_flushAll();
3223
+ await act(() => {
3224
+ ReactDOM.render(<Test />, container);
3225
+ });
3226
3227
const buttonElement = buttonRef.current;
3228
dispatchClickEvent(buttonElement);
@@ -3190,7 +3231,7 @@ describe('DOMPluginEventSystem', () => {
3231
});
3232
3233
// @gate www
3193
- it('should be able to register handlers for events affected by the intervention', () => {
3234
+ it('should be able to register handlers for events affected by the intervention', async () => {
3235
const rootContainer = document.createElement('div');
3236
container.appendChild(rootContainer);
3237
@@ -3232,8 +3273,9 @@ describe('DOMPluginEventSystem', () => {
3273
return <div ref={ref}>test</div>;
3274
}
3275
3235
- ReactDOM.render(<Component />, rootContainer);
3236
- Scheduler.unstable_flushAll();
3276
+ await act(() => {
3277
+ ReactDOM.render(<Component />, rootContainer);
3278
+ });
3279
3280
dispatchEvent(ref.current, 'touchstart');
3281
dispatchEvent(ref.current, 'touchmove');
packages/react-interactions/events/src/dom/create-event-handle/__tests__/useFocus-test.internal.js
+46
-42
@@ -15,7 +15,7 @@ let React;
15
let ReactFeatureFlags;
16
let ReactDOM;
17
let useFocus;
18
-let Scheduler;
18
+let act;
19
20
function initializeModules(hasPointerEvents) {
21
setPointerEvent(hasPointerEvents);
@@ -24,8 +24,7 @@ function initializeModules(hasPointerEvents) {
24
ReactFeatureFlags.enableCreateEventHandleAPI = true;
25
React = require('react');
26
ReactDOM = require('react-dom');
27
- Scheduler = require('scheduler');
28
-
27
+ act = require('internal-test-utils').act;
28
// TODO: This import throws outside of experimental mode. Figure out better
29
// strategy for gated imports.
30
if (__EXPERIMENTAL__ || global.__WWW__) {
@@ -54,7 +53,7 @@ describe.each(table)(`useFocus hasPointerEvents=%s`, hasPointerEvents => {
53
describe('disabled', () => {
54
let onBlur, onFocus, ref;
55
57
- const componentInit = () => {
56
+ const componentInit = async () => {
57
onBlur = jest.fn();
58
onFocus = jest.fn();
59
ref = React.createRef();
@@ -66,13 +65,14 @@ describe.each(table)(`useFocus hasPointerEvents=%s`, hasPointerEvents => {
65
});
66
return <div ref={ref} />;
67
};
69
- ReactDOM.render(<Component />, container);
70
- Scheduler.unstable_flushAll();
68
+ await act(() => {
69
+ ReactDOM.render(<Component />, container);
70
+ });
71
};
72
73
// @gate www
74
- it('does not call callbacks', () => {
75
- componentInit();
74
+ it('does not call callbacks', async () => {
75
+ await componentInit();
76
const target = createEventTarget(ref.current);
77
target.focus();
78
target.blur();
@@ -84,7 +84,7 @@ describe.each(table)(`useFocus hasPointerEvents=%s`, hasPointerEvents => {
84
describe('onBlur', () => {
85
let onBlur, ref;
86
87
- const componentInit = () => {
87
+ const componentInit = async () => {
88
onBlur = jest.fn();
89
ref = React.createRef();
90
const Component = () => {
@@ -93,13 +93,14 @@ describe.each(table)(`useFocus hasPointerEvents=%s`, hasPointerEvents => {
93
});
94
return <div ref={ref} />;
95
};
96
- ReactDOM.render(<Component />, container);
97
- Scheduler.unstable_flushAll();
96
+ await act(() => {
97
+ ReactDOM.render(<Component />, container);
98
+ });
99
};
100
101
// @gate www
101
- it('is called after "blur" event', () => {
102
- componentInit();
102
+ it('is called after "blur" event', async () => {
103
+ await componentInit();
104
const target = createEventTarget(ref.current);
105
target.focus();
106
target.blur();
@@ -110,7 +111,7 @@ describe.each(table)(`useFocus hasPointerEvents=%s`, hasPointerEvents => {
111
describe('onFocus', () => {
112
let onFocus, ref, innerRef;
113
113
- const componentInit = () => {
114
+ const componentInit = async () => {
115
onFocus = jest.fn();
116
ref = React.createRef();
117
innerRef = React.createRef();
@@ -124,21 +125,22 @@ describe.each(table)(`useFocus hasPointerEvents=%s`, hasPointerEvents => {
125
</div>
126
);
127
};
127
- ReactDOM.render(<Component />, container);
128
- Scheduler.unstable_flushAll();
128
+ await act(() => {
129
+ ReactDOM.render(<Component />, container);
130
+ });
131
};
132
133
// @gate www
132
- it('is called after "focus" event', () => {
133
- componentInit();
134
+ it('is called after "focus" event', async () => {
135
+ await componentInit();
136
const target = createEventTarget(ref.current);
137
target.focus();
138
expect(onFocus).toHaveBeenCalledTimes(1);
139
});
140
141
// @gate www
140
- it('is not called if descendants of target receive focus', () => {
141
- componentInit();
142
+ it('is not called if descendants of target receive focus', async () => {
143
+ await componentInit();
144
const target = createEventTarget(innerRef.current);
145
target.focus();
146
expect(onFocus).not.toBeCalled();
@@ -148,7 +150,7 @@ describe.each(table)(`useFocus hasPointerEvents=%s`, hasPointerEvents => {
150
describe('onFocusChange', () => {
151
let onFocusChange, ref, innerRef;
152
151
- const componentInit = () => {
153
+ const componentInit = async () => {
154
onFocusChange = jest.fn();
155
ref = React.createRef();
156
innerRef = React.createRef();
@@ -162,13 +164,14 @@ describe.each(table)(`useFocus hasPointerEvents=%s`, hasPointerEvents => {
164
</div>
165
);
166
};
165
- ReactDOM.render(<Component />, container);
166
- Scheduler.unstable_flushAll();
167
+ await act(() => {
168
+ ReactDOM.render(<Component />, container);
169
+ });
170
};
171
172
// @gate www
170
- it('is called after "blur" and "focus" events', () => {
171
- componentInit();
173
+ it('is called after "blur" and "focus" events', async () => {
174
+ await componentInit();
175
const target = createEventTarget(ref.current);
176
target.focus();
177
expect(onFocusChange).toHaveBeenCalledTimes(1);
@@ -179,8 +182,8 @@ describe.each(table)(`useFocus hasPointerEvents=%s`, hasPointerEvents => {
182
});
183
184
// @gate www
182
- it('is not called after "blur" and "focus" events on descendants', () => {
183
- componentInit();
185
+ it('is not called after "blur" and "focus" events on descendants', async () => {
186
+ await componentInit();
187
const target = createEventTarget(innerRef.current);
188
target.focus();
189
expect(onFocusChange).toHaveBeenCalledTimes(0);
@@ -192,7 +195,7 @@ describe.each(table)(`useFocus hasPointerEvents=%s`, hasPointerEvents => {
195
describe('onFocusVisibleChange', () => {
196
let onFocusVisibleChange, ref, innerRef;
197
195
- const componentInit = () => {
198
+ const componentInit = async () => {
199
onFocusVisibleChange = jest.fn();
200
ref = React.createRef();
201
innerRef = React.createRef();
@@ -206,13 +209,14 @@ describe.each(table)(`useFocus hasPointerEvents=%s`, hasPointerEvents => {
209
</div>
210
);
211
};
209
- ReactDOM.render(<Component />, container);
210
- Scheduler.unstable_flushAll();
212
+ await act(() => {
213
+ ReactDOM.render(<Component />, container);
214
+ });
215
};
216
217
// @gate www
214
- it('is called after "focus" and "blur" if keyboard navigation is active', () => {
215
- componentInit();
218
+ it('is called after "focus" and "blur" if keyboard navigation is active', async () => {
219
+ await componentInit();
220
const target = createEventTarget(ref.current);
221
const containerTarget = createEventTarget(container);
222
// use keyboard first
@@ -226,8 +230,8 @@ describe.each(table)(`useFocus hasPointerEvents=%s`, hasPointerEvents => {
230
});
231
232
// @gate www
229
- it('is called if non-keyboard event is dispatched on target previously focused with keyboard', () => {
230
- componentInit();
233
+ it('is called if non-keyboard event is dispatched on target previously focused with keyboard', async () => {
234
+ await componentInit();
235
const target = createEventTarget(ref.current);
236
const containerTarget = createEventTarget(container);
237
// use keyboard first
@@ -245,8 +249,8 @@ describe.each(table)(`useFocus hasPointerEvents=%s`, hasPointerEvents => {
249
});
250
251
// @gate www
248
- it('is not called after "focus" and "blur" events without keyboard', () => {
249
- componentInit();
252
+ it('is not called after "focus" and "blur" events without keyboard', async () => {
253
+ await componentInit();
254
const target = createEventTarget(ref.current);
255
const containerTarget = createEventTarget(container);
256
target.pointerdown();
@@ -257,8 +261,8 @@ describe.each(table)(`useFocus hasPointerEvents=%s`, hasPointerEvents => {
261
});
262
263
// @gate www
260
- it('is not called after "blur" and "focus" events on descendants', () => {
261
- componentInit();
264
+ it('is not called after "blur" and "focus" events on descendants', async () => {
265
+ await componentInit();
266
const innerTarget = createEventTarget(innerRef.current);
267
const containerTarget = createEventTarget(container);
268
containerTarget.keydown({key: 'Tab'});
@@ -271,7 +275,7 @@ describe.each(table)(`useFocus hasPointerEvents=%s`, hasPointerEvents => {
275
276
describe('nested Focus components', () => {
277
// @gate www
274
- it('propagates events in the correct order', () => {
278
+ it('propagates events in the correct order', async () => {
279
const events = [];
280
const innerRef = React.createRef();
281
const outerRef = React.createRef();
@@ -301,9 +305,9 @@ describe.each(table)(`useFocus hasPointerEvents=%s`, hasPointerEvents => {
305
);
306
};
307
304
- ReactDOM.render(<Outer />, container);
305
- Scheduler.unstable_flushAll();
306
-
308
+ await act(() => {
309
+ ReactDOM.render(<Outer />, container);
310
+ });
311
const innerTarget = createEventTarget(innerRef.current);
312
const outerTarget = createEventTarget(outerRef.current);
313
packages/react-interactions/events/src/dom/create-event-handle/__tests__/useFocusWithin-test.internal.js
+49
-49
@@ -17,7 +17,6 @@ let ReactDOM;
17
let ReactDOMClient;
18
let useFocusWithin;
19
let act;
20
-let Scheduler;
20
21
function initializeModules(hasPointerEvents) {
22
setPointerEvent(hasPointerEvents);
@@ -28,7 +27,6 @@ function initializeModules(hasPointerEvents) {
27
React = require('react');
28
ReactDOM = require('react-dom');
29
ReactDOMClient = require('react-dom/client');
31
- Scheduler = require('scheduler');
30
act = require('internal-test-utils').act;
31
32
// TODO: This import throws outside of experimental mode. Figure out better
@@ -64,7 +62,7 @@ describe.each(table)(`useFocus`, hasPointerEvents => {
62
describe('disabled', () => {
63
let onFocusWithinChange, onFocusWithinVisibleChange, ref;
64
67
- const componentInit = () => {
65
+ const componentInit = async () => {
66
onFocusWithinChange = jest.fn();
67
onFocusWithinVisibleChange = jest.fn();
68
ref = React.createRef();
@@ -76,13 +74,14 @@ describe.each(table)(`useFocus`, hasPointerEvents => {
74
});
75
return <div ref={focusWithinRef} />;
76
};
79
- ReactDOM.render(<Component />, container);
80
- Scheduler.unstable_flushAll();
77
+ await act(() => {
78
+ ReactDOM.render(<Component />, container);
79
+ });
80
};
81
82
// @gate www
84
- it('prevents custom events being dispatched', () => {
85
- componentInit();
83
+ it('prevents custom events being dispatched', async () => {
84
+ await componentInit();
85
const target = createEventTarget(ref.current);
86
target.focus();
87
target.blur();
@@ -106,18 +105,19 @@ describe.each(table)(`useFocus`, hasPointerEvents => {
105
);
106
};
107
109
- const componentInit = () => {
108
+ const componentInit = async () => {
109
onFocusWithinChange = jest.fn();
110
ref = React.createRef();
111
innerRef = React.createRef();
112
innerRef2 = React.createRef();
114
- ReactDOM.render(<Component show={true} />, container);
115
- Scheduler.unstable_flushAll();
113
+ await act(() => {
114
+ ReactDOM.render(<Component show={true} />, container);
115
+ });
116
};
117
118
// @gate www
119
- it('is called after "blur" and "focus" events on focus target', () => {
120
- componentInit();
119
+ it('is called after "blur" and "focus" events on focus target', async () => {
120
+ await componentInit();
121
const target = createEventTarget(ref.current);
122
target.focus();
123
expect(onFocusWithinChange).toHaveBeenCalledTimes(1);
@@ -128,8 +128,8 @@ describe.each(table)(`useFocus`, hasPointerEvents => {
128
});
129
130
// @gate www
131
- it('is called after "blur" and "focus" events on descendants', () => {
132
- componentInit();
131
+ it('is called after "blur" and "focus" events on descendants', async () => {
132
+ await componentInit();
133
const target = createEventTarget(innerRef.current);
134
target.focus();
135
expect(onFocusWithinChange).toHaveBeenCalledTimes(1);
@@ -140,8 +140,8 @@ describe.each(table)(`useFocus`, hasPointerEvents => {
140
});
141
142
// @gate www
143
- it('is only called once when focus moves within and outside the subtree', () => {
144
- componentInit();
143
+ it('is only called once when focus moves within and outside the subtree', async () => {
144
+ await componentInit();
145
const node = ref.current;
146
const innerNode1 = innerRef.current;
147
const innerNode2 = innerRef.current;
@@ -182,18 +182,19 @@ describe.each(table)(`useFocus`, hasPointerEvents => {
182
);
183
};
184
185
- const componentInit = () => {
185
+ const componentInit = async () => {
186
onFocusWithinVisibleChange = jest.fn();
187
ref = React.createRef();
188
innerRef = React.createRef();
189
innerRef2 = React.createRef();
190
- ReactDOM.render(<Component show={true} />, container);
191
- Scheduler.unstable_flushAll();
190
+ await act(() => {
191
+ ReactDOM.render(<Component show={true} />, container);
192
+ });
193
};
194
195
// @gate www
195
- it('is called after "focus" and "blur" on focus target if keyboard was used', () => {
196
- componentInit();
196
+ it('is called after "focus" and "blur" on focus target if keyboard was used', async () => {
197
+ await componentInit();
198
const target = createEventTarget(ref.current);
199
const containerTarget = createEventTarget(container);
200
// use keyboard first
@@ -207,8 +208,8 @@ describe.each(table)(`useFocus`, hasPointerEvents => {
208
});
209
210
// @gate www
210
- it('is called after "focus" and "blur" on descendants if keyboard was used', () => {
211
- componentInit();
211
+ it('is called after "focus" and "blur" on descendants if keyboard was used', async () => {
212
+ await componentInit();
213
const innerTarget = createEventTarget(innerRef.current);
214
const containerTarget = createEventTarget(container);
215
// use keyboard first
@@ -222,8 +223,8 @@ describe.each(table)(`useFocus`, hasPointerEvents => {
223
});
224
225
// @gate www
225
- it('is called if non-keyboard event is dispatched on target previously focused with keyboard', () => {
226
- componentInit();
226
+ it('is called if non-keyboard event is dispatched on target previously focused with keyboard', async () => {
227
+ await componentInit();
228
const node = ref.current;
229
const innerNode1 = innerRef.current;
230
const innerNode2 = innerRef2.current;
@@ -260,8 +261,8 @@ describe.each(table)(`useFocus`, hasPointerEvents => {
261
});
262
263
// @gate www
263
- it('is not called after "focus" and "blur" events without keyboard', () => {
264
- componentInit();
264
+ it('is not called after "focus" and "blur" events without keyboard', async () => {
265
+ await componentInit();
266
const innerTarget = createEventTarget(innerRef.current);
267
innerTarget.pointerdown();
268
innerTarget.pointerup();
@@ -270,8 +271,8 @@ describe.each(table)(`useFocus`, hasPointerEvents => {
271
});
272
273
// @gate www
273
- it('is only called once when focus moves within and outside the subtree', () => {
274
- componentInit();
274
+ it('is only called once when focus moves within and outside the subtree', async () => {
275
+ await componentInit();
276
const node = ref.current;
277
const innerNode1 = innerRef.current;
278
const innerNode2 = innerRef2.current;
@@ -338,7 +339,7 @@ describe.each(table)(`useFocus`, hasPointerEvents => {
339
});
340
341
// @gate www
341
- it('is called after a focused element is unmounted', () => {
342
+ it('is called after a focused element is unmounted', async () => {
343
const Component = ({show}) => {
344
const focusWithinRef = useFocusWithin(ref, {
345
onBeforeBlurWithin,
@@ -352,8 +353,9 @@ describe.each(table)(`useFocus`, hasPointerEvents => {
353
);
354
};
355
355
- ReactDOM.render(<Component show={true} />, container);
356
- Scheduler.unstable_flushAll();
356
+ await act(() => {
357
+ ReactDOM.render(<Component show={true} />, container);
358
+ });
359
360
const inner = innerRef.current;
361
const target = createEventTarget(inner);
@@ -370,7 +372,7 @@ describe.each(table)(`useFocus`, hasPointerEvents => {
372
});
373
374
// @gate www
373
- it('is called after a nested focused element is unmounted', () => {
375
+ it('is called after a nested focused element is unmounted', async () => {
376
const Component = ({show}) => {
377
const focusWithinRef = useFocusWithin(ref, {
378
onBeforeBlurWithin,
@@ -388,8 +390,9 @@ describe.each(table)(`useFocus`, hasPointerEvents => {
390
);
391
};
392
391
- ReactDOM.render(<Component show={true} />, container);
392
- Scheduler.unstable_flushAll();
393
+ await act(() => {
394
+ ReactDOM.render(<Component show={true} />, container);
395
+ });
396
397
const inner = innerRef.current;
398
const target = createEventTarget(inner);
@@ -406,7 +409,7 @@ describe.each(table)(`useFocus`, hasPointerEvents => {
409
});
410
411
// @gate www
409
- it('is called after many elements are unmounted', () => {
412
+ it('is called after many elements are unmounted', async () => {
413
const buttonRef = React.createRef();
414
const inputRef = React.createRef();
415
@@ -429,8 +432,9 @@ describe.each(table)(`useFocus`, hasPointerEvents => {
432
);
433
};
434
432
- ReactDOM.render(<Component show={true} />, container);
433
- Scheduler.unstable_flushAll();
435
+ await act(() => {
436
+ ReactDOM.render(<Component show={true} />, container);
437
+ });
438
439
inputRef.current.focus();
440
expect(onBeforeBlurWithin).toHaveBeenCalledTimes(0);
@@ -441,7 +445,7 @@ describe.each(table)(`useFocus`, hasPointerEvents => {
445
});
446
447
// @gate www
444
- it('is called after a nested focused element is unmounted (with scope query)', () => {
448
+ it('is called after a nested focused element is unmounted (with scope query)', async () => {
449
const TestScope = React.unstable_Scope;
450
const testScopeQuery = (type, props) => true;
451
let targetNodes;
@@ -464,15 +468,17 @@ describe.each(table)(`useFocus`, hasPointerEvents => {
468
);
469
};
470
467
- ReactDOM.render(<Component show={true} />, container);
468
- Scheduler.unstable_flushAll();
471
+ await act(() => {
472
+ ReactDOM.render(<Component show={true} />, container);
473
+ });
474
475
const inner = innerRef.current;
476
const target = createEventTarget(inner);
477
target.keydown({key: 'Tab'});
478
target.focus();
474
- ReactDOM.render(<Component show={false} />, container);
475
- Scheduler.unstable_flushAll();
479
+ await act(() => {
480
+ ReactDOM.render(<Component show={false} />, container);
481
+ });
482
expect(targetNodes).toEqual([targetNode]);
483
});
484
@@ -511,7 +517,6 @@ describe.each(table)(`useFocus`, hasPointerEvents => {
517
await act(() => {
518
root.render(<Component />);
519
});
514
- jest.runAllTimers();
520
expect(container2.innerHTML).toBe('<div><input></div>');
521
522
const inner = innerRef.current;
@@ -525,7 +530,6 @@ describe.each(table)(`useFocus`, hasPointerEvents => {
530
await act(() => {
531
root.render(<Component />);
532
});
528
- jest.runAllTimers();
533
expect(container2.innerHTML).toBe(
534
'<div><input style="display: none;">Loading...</div>',
535
);
@@ -570,7 +574,6 @@ describe.each(table)(`useFocus`, hasPointerEvents => {
574
await act(() => {
575
root.render(<Component />);
576
});
573
- jest.runAllTimers();
577
578
expect(onBeforeBlurWithin).toHaveBeenCalledTimes(0);
579
expect(onAfterBlurWithin).toHaveBeenCalledTimes(0);
@@ -579,14 +582,12 @@ describe.each(table)(`useFocus`, hasPointerEvents => {
582
await act(() => {
583
root.render(<Component />);
584
});
582
- jest.runAllTimers();
585
expect(onBeforeBlurWithin).toHaveBeenCalledTimes(0);
586
expect(onAfterBlurWithin).toHaveBeenCalledTimes(0);
587
588
await act(() => {
589
root.render(<Component />);
590
});
589
- jest.runAllTimers();
591
expect(onBeforeBlurWithin).toHaveBeenCalledTimes(0);
592
expect(onAfterBlurWithin).toHaveBeenCalledTimes(0);
593
@@ -595,7 +596,6 @@ describe.each(table)(`useFocus`, hasPointerEvents => {
596
await act(() => {
597
root.render(<Component />);
598
});
598
- jest.runAllTimers();
599
expect(onBeforeBlurWithin).toHaveBeenCalledTimes(1);
600
expect(onAfterBlurWithin).toHaveBeenCalledTimes(1);
601
packages/react-reconciler/src/__tests__/ErrorBoundaryReconciliation-test.internal.js
+19
-16
@@ -5,8 +5,8 @@ describe('ErrorBoundaryReconciliation', () => {
5
let React;
6
let ReactFeatureFlags;
7
let ReactTestRenderer;
8
- let Scheduler;
8
let span;
9
+ let act;
10
11
beforeEach(() => {
12
jest.resetModules();
@@ -16,8 +16,7 @@ describe('ErrorBoundaryReconciliation', () => {
16
ReactFeatureFlags.replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
17
ReactTestRenderer = require('react-test-renderer');
18
React = require('react');
19
- Scheduler = require('scheduler');
20
-
19
+ act = require('internal-test-utils').act;
20
DidCatchErrorBoundary = class extends React.Component {
21
state = {error: null};
22
componentDidCatch(error) {
@@ -52,23 +51,27 @@ describe('ErrorBoundaryReconciliation', () => {
51
});
52
53
[true, false].forEach(isConcurrent => {
55
- function sharedTest(ErrorBoundary, fallbackTagName) {
56
- const renderer = ReactTestRenderer.create(
57
- <ErrorBoundary fallbackTagName={fallbackTagName}>
58
- <BrokenRender fail={false} />
59
- </ErrorBoundary>,
60
- {unstable_isConcurrent: isConcurrent},
61
- );
62
- Scheduler.unstable_flushAll();
63
- expect(renderer).toMatchRenderedOutput(<span prop="BrokenRender" />);
54
+ async function sharedTest(ErrorBoundary, fallbackTagName) {
55
+ let renderer;
56
65
- expect(() => {
66
- renderer.update(
57
+ await act(() => {
58
+ renderer = ReactTestRenderer.create(
59
<ErrorBoundary fallbackTagName={fallbackTagName}>
68
- <BrokenRender fail={true} />
60
+ <BrokenRender fail={false} />
61
</ErrorBoundary>,
62
+ {unstable_isConcurrent: isConcurrent},
63
);
71
- Scheduler.unstable_flushAll();
64
+ });
65
+ expect(renderer).toMatchRenderedOutput(<span prop="BrokenRender" />);
66
+
67
+ await expect(async () => {
68
+ await act(() => {
69
+ renderer.update(
70
+ <ErrorBoundary fallbackTagName={fallbackTagName}>
71
+ <BrokenRender fail={true} />
72
+ </ErrorBoundary>,
73
+ );
74
+ });
75
}).toErrorDev(isConcurrent ? ['invalid', 'invalid'] : ['invalid']);
76
const Fallback = fallbackTagName;
77
expect(renderer).toMatchRenderedOutput(<Fallback prop="ErrorBoundary" />);
packages/react-reconciler/src/__tests__/ReactSuspenseList-test.js
+52
-36
@@ -16,7 +16,6 @@ describe('ReactSuspenseList', () => {
16
React = require('react');
17
ReactNoop = require('react-noop-renderer');
18
Scheduler = require('scheduler');
19
- act = require('internal-test-utils').act;
19
Profiler = React.Profiler;
20
Suspense = React.Suspense;
21
if (gate(flags => flags.enableSuspenseList)) {
@@ -27,6 +26,7 @@ describe('ReactSuspenseList', () => {
26
waitForAll = InternalTestUtils.waitForAll;
27
assertLog = InternalTestUtils.assertLog;
28
waitFor = InternalTestUtils.waitFor;
29
+ act = InternalTestUtils.act;
30
});
31
32
function Text(props) {
@@ -53,7 +53,7 @@ describe('ReactSuspenseList', () => {
53
}
54
55
// @gate enableSuspenseList
56
- it('warns if an unsupported revealOrder option is used', () => {
56
+ it('warns if an unsupported revealOrder option is used', async () => {
57
function Foo() {
58
return (
59
<SuspenseList revealOrder="something">
@@ -62,9 +62,11 @@ describe('ReactSuspenseList', () => {
62
);
63
}
64
65
- ReactNoop.render(<Foo />);
66
-
67
- expect(() => Scheduler.unstable_flushAll()).toErrorDev([
65
+ await expect(async () => {
66
+ await act(() => {
67
+ ReactNoop.render(<Foo />);
68
+ });
69
+ }).toErrorDev([
70
'Warning: "something" is not a supported revealOrder on ' +
71
'<SuspenseList />. Did you mean "together", "forwards" or "backwards"?' +
72
'\n in SuspenseList (at **)' +
@@ -73,7 +75,7 @@ describe('ReactSuspenseList', () => {
75
});
76
77
// @gate enableSuspenseList
76
- it('warns if a upper case revealOrder option is used', () => {
78
+ it('warns if a upper case revealOrder option is used', async () => {
79
function Foo() {
80
return (
81
<SuspenseList revealOrder="TOGETHER">
@@ -82,9 +84,11 @@ describe('ReactSuspenseList', () => {
84
);
85
}
86
85
- ReactNoop.render(<Foo />);
86
-
87
- expect(() => Scheduler.unstable_flushAll()).toErrorDev([
87
+ await expect(async () => {
88
+ await act(() => {
89
+ ReactNoop.render(<Foo />);
90
+ });
91
+ }).toErrorDev([
92
'Warning: "TOGETHER" is not a valid value for revealOrder on ' +
93
'<SuspenseList />. Use lowercase "together" instead.' +
94
'\n in SuspenseList (at **)' +
@@ -93,7 +97,7 @@ describe('ReactSuspenseList', () => {
97
});
98
99
// @gate enableSuspenseList
96
- it('warns if a misspelled revealOrder option is used', () => {
100
+ it('warns if a misspelled revealOrder option is used', async () => {
101
function Foo() {
102
return (
103
<SuspenseList revealOrder="forward">
@@ -102,9 +106,11 @@ describe('ReactSuspenseList', () => {
106
);
107
}
108
105
- ReactNoop.render(<Foo />);
106
-
107
- expect(() => Scheduler.unstable_flushAll()).toErrorDev([
109
+ await expect(async () => {
110
+ await act(() => {
111
+ ReactNoop.render(<Foo />);
112
+ });
113
+ }).toErrorDev([
114
'Warning: "forward" is not a valid value for revealOrder on ' +
115
'<SuspenseList />. React uses the -s suffix in the spelling. ' +
116
'Use "forwards" instead.' +
@@ -131,13 +137,15 @@ describe('ReactSuspenseList', () => {
137
// No warning
138
await waitForAll([]);
139
134
- ReactNoop.render(
135
- <Foo>
136
- <Suspense fallback="Loading">Child</Suspense>
137
- </Foo>,
138
- );
139
-
140
- expect(() => Scheduler.unstable_flushAll()).toErrorDev([
140
+ await expect(async () => {
141
+ await act(() => {
142
+ ReactNoop.render(
143
+ <Foo>
144
+ <Suspense fallback="Loading">Child</Suspense>
145
+ </Foo>,
146
+ );
147
+ });
148
+ }).toErrorDev([
149
'Warning: A single row was passed to a <SuspenseList revealOrder="forwards" />. ' +
150
'This is not useful since it needs multiple rows. ' +
151
'Did you mean to pass multiple children or an array?' +
@@ -147,7 +155,7 @@ describe('ReactSuspenseList', () => {
155
});
156
157
// @gate enableSuspenseList
150
- it('warns if a single fragment is passed to a "backwards" list', () => {
158
+ it('warns if a single fragment is passed to a "backwards" list', async () => {
159
function Foo() {
160
return (
161
<SuspenseList revealOrder="backwards">
@@ -156,9 +164,11 @@ describe('ReactSuspenseList', () => {
164
);
165
}
166
159
- ReactNoop.render(<Foo />);
160
-
161
- expect(() => Scheduler.unstable_flushAll()).toErrorDev([
167
+ await expect(async () => {
168
+ await act(() => {
169
+ ReactNoop.render(<Foo />);
170
+ });
171
+ }).toErrorDev([
172
'Warning: A single row was passed to a <SuspenseList revealOrder="backwards" />. ' +
173
'This is not useful since it needs multiple rows. ' +
174
'Did you mean to pass multiple children or an array?' +
@@ -168,7 +178,7 @@ describe('ReactSuspenseList', () => {
178
});
179
180
// @gate enableSuspenseList
171
- it('warns if a nested array is passed to a "forwards" list', () => {
181
+ it('warns if a nested array is passed to a "forwards" list', async () => {
182
function Foo({items}) {
183
return (
184
<SuspenseList revealOrder="forwards">
@@ -182,9 +192,11 @@ describe('ReactSuspenseList', () => {
192
);
193
}
194
185
- ReactNoop.render(<Foo items={['A', 'B']} />);
186
-
187
- expect(() => Scheduler.unstable_flushAll()).toErrorDev([
195
+ await expect(async () => {
196
+ await act(() => {
197
+ ReactNoop.render(<Foo items={['A', 'B']} />);
198
+ });
199
+ }).toErrorDev([
200
'Warning: A nested array was passed to row #0 in <SuspenseList />. ' +
201
'Wrap it in an additional SuspenseList to configure its revealOrder: ' +
202
'<SuspenseList revealOrder=...> ... ' +
@@ -1471,7 +1483,7 @@ describe('ReactSuspenseList', () => {
1483
});
1484
1485
// @gate enableSuspenseList
1474
- it('warns if an unsupported tail option is used', () => {
1486
+ it('warns if an unsupported tail option is used', async () => {
1487
function Foo() {
1488
return (
1489
<SuspenseList revealOrder="forwards" tail="collapse">
@@ -1481,9 +1493,11 @@ describe('ReactSuspenseList', () => {
1493
);
1494
}
1495
1484
- ReactNoop.render(<Foo />);
1485
-
1486
- expect(() => Scheduler.unstable_flushAll()).toErrorDev([
1496
+ await expect(async () => {
1497
+ await act(() => {
1498
+ ReactNoop.render(<Foo />);
1499
+ });
1500
+ }).toErrorDev([
1501
'Warning: "collapse" is not a supported value for tail on ' +
1502
'<SuspenseList />. Did you mean "collapsed" or "hidden"?' +
1503
'\n in SuspenseList (at **)' +
@@ -1492,7 +1506,7 @@ describe('ReactSuspenseList', () => {
1506
});
1507
1508
// @gate enableSuspenseList
1495
- it('warns if a tail option is used with "together"', () => {
1509
+ it('warns if a tail option is used with "together"', async () => {
1510
function Foo() {
1511
return (
1512
<SuspenseList revealOrder="together" tail="collapsed">
@@ -1501,9 +1515,11 @@ describe('ReactSuspenseList', () => {
1515
);
1516
}
1517
1504
- ReactNoop.render(<Foo />);
1505
-
1506
- expect(() => Scheduler.unstable_flushAll()).toErrorDev([
1518
+ await expect(async () => {
1519
+ await act(() => {
1520
+ ReactNoop.render(<Foo />);
1521
+ });
1522
+ }).toErrorDev([
1523
'Warning: <SuspenseList tail="collapsed" /> is only valid if ' +
1524
'revealOrder is "forwards" or "backwards". ' +
1525
'Did you mean to specify revealOrder="forwards"?' +
packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.js
+7
-10
@@ -13,7 +13,7 @@ let ReactDOM;
13
let React;
14
let ReactCache;
15
let ReactTestRenderer;
16
-let Scheduler;
16
+let waitForAll;
17
18
describe('ReactTestRenderer', () => {
19
beforeEach(() => {
@@ -25,7 +25,8 @@ describe('ReactTestRenderer', () => {
25
React = require('react');
26
ReactCache = require('react-cache');
27
ReactTestRenderer = require('react-test-renderer');
28
- Scheduler = require('scheduler');
28
+ const InternalTestUtils = require('internal-test-utils');
29
+ waitForAll = InternalTestUtils.waitForAll;
30
});
31
32
it('should warn if used to render a ReactDOM portal', () => {
@@ -85,16 +86,14 @@ describe('ReactTestRenderer', () => {
86
87
const root = ReactTestRenderer.create(<App text="initial" />);
88
PendingResources.initial('initial');
88
- await Promise.resolve();
89
- Scheduler.unstable_flushAll();
89
+ await waitForAll([]);
90
expect(root.toJSON()).toEqual('initial');
91
92
root.update(<App text="dynamic" />);
93
expect(root.toJSON()).toEqual('fallback');
94
95
PendingResources.dynamic('dynamic');
96
- await Promise.resolve();
97
- Scheduler.unstable_flushAll();
96
+ await waitForAll([]);
97
expect(root.toJSON()).toEqual('dynamic');
98
});
99
@@ -111,16 +110,14 @@ describe('ReactTestRenderer', () => {
110
111
const root = ReactTestRenderer.create(<App text="initial" />);
112
PendingResources.initial('initial');
114
- await Promise.resolve();
115
- Scheduler.unstable_flushAll();
113
+ await waitForAll([]);
114
expect(root.toJSON().children).toEqual(['initial']);
115
116
root.update(<App text="dynamic" />);
117
expect(root.toJSON().children).toEqual(['fallback']);
118
119
PendingResources.dynamic('dynamic');
122
- await Promise.resolve();
123
- Scheduler.unstable_flushAll();
120
+ await waitForAll([]);
121
expect(root.toJSON().children).toEqual(['dynamic']);
122
});
123
});