chore: use versioned render in inspectedElement test (#28246)
Ruslan Lesiutin committed
Feb 7, 2024 at 10:50 UTC
bfdc12c1912143ae4ec6d7466e619130adc911c5
1 file changed
+291
-182
packages/react-devtools-shared/src/__tests__/inspectedElement-test.js
+291
-182
@@ -8,7 +8,12 @@
8
*/
9
10
import typeof ReactTestRenderer from 'react-test-renderer';
11
-import {withErrorsOrWarningsIgnored} from 'react-devtools-shared/src/__tests__/utils';
11
+import {
12
+ withErrorsOrWarningsIgnored,
13
+ getLegacyRenderImplementation,
14
+ getModernRenderImplementation,
15
+ getVersionedRenderImplementation,
16
+} from 'react-devtools-shared/src/__tests__/utils';
17
18
import type {FrontendBridge} from 'react-devtools-shared/src/bridge';
19
import type Store from 'react-devtools-shared/src/devtools/store';
@@ -33,7 +38,6 @@ describe('InspectedElement', () => {
38
let TestUtilsAct;
39
let TestRendererAct;
40
36
- let legacyRender;
41
let testRendererInstance;
42
43
let ErrorBoundary;
@@ -45,8 +49,6 @@ describe('InspectedElement', () => {
49
utils = require('./utils');
50
utils.beforeEachProfiling();
51
48
- legacyRender = utils.legacyRender;
49
-
52
bridge = global.bridge;
53
store = global.store;
54
store.collapseNodesByDefault = false;
@@ -101,6 +103,10 @@ describe('InspectedElement', () => {
103
jest.restoreAllMocks();
104
});
105
106
+ const {render: legacyRender} = getLegacyRenderImplementation();
107
+ const {render: modernRender} = getModernRenderImplementation();
108
+ const {render} = getVersionedRenderImplementation();
109
+
110
const Contexts = ({
111
children,
112
defaultSelectedElementID = null,
@@ -173,16 +179,17 @@ describe('InspectedElement', () => {
179
return inspectedElement;
180
}
181
176
- it('should inspect the currently selected element', async () => {
182
+ // TODO(hoxyq): Enable this test for versions ~18, currently broken
183
+ // @reactVersion <= 18.2
184
+ xit('should inspect the currently selected element (legacy render)', async () => {
185
const Example = () => {
186
const [count] = React.useState(1);
187
return count;
188
};
189
182
- const container = document.createElement('div');
183
- await utils.actAsync(() =>
184
- legacyRender(<Example a={1} b="abc" />, container),
185
- );
190
+ await utils.actAsync(() => {
191
+ legacyRender(<Example a={1} b="abc" />);
192
+ });
193
194
const inspectedElement = await inspectElementAtIndex(0);
195
expect(inspectedElement).toMatchInlineSnapshot(`
@@ -216,6 +223,48 @@ describe('InspectedElement', () => {
223
`);
224
});
225
226
+ it('should inspect the currently selected element (createRoot)', async () => {
227
+ const Example = () => {
228
+ const [count] = React.useState(1);
229
+ return count;
230
+ };
231
+
232
+ await utils.actAsync(() => {
233
+ modernRender(<Example a={1} b="abc" />);
234
+ });
235
+
236
+ const inspectedElement = await inspectElementAtIndex(0);
237
+ expect(inspectedElement).toMatchInlineSnapshot(`
238
+ {
239
+ "context": null,
240
+ "events": undefined,
241
+ "hooks": [
242
+ {
243
+ "hookSource": {
244
+ "columnNumber": "removed by Jest serializer",
245
+ "fileName": "react-devtools-shared/src/__tests__/inspectedElement-test.js",
246
+ "functionName": "Example",
247
+ "lineNumber": "removed by Jest serializer",
248
+ },
249
+ "id": 0,
250
+ "isStateEditable": true,
251
+ "name": "State",
252
+ "subHooks": [],
253
+ "value": 1,
254
+ },
255
+ ],
256
+ "id": 2,
257
+ "owners": null,
258
+ "props": {
259
+ "a": 1,
260
+ "b": "abc",
261
+ },
262
+ "rootType": "createRoot()",
263
+ "state": null,
264
+ }
265
+ `);
266
+ });
267
+
268
it('should have hasLegacyContext flag set to either "true" or "false" depending on which context API is used.', async () => {
269
const contextData = {
270
bool: true,
@@ -256,9 +305,8 @@ describe('InspectedElement', () => {
305
const ModernContext = React.createContext();
306
ModernContext.displayName = 'ModernContext';
307
259
- const container = document.createElement('div');
308
await utils.actAsync(() =>
261
- legacyRender(
309
+ render(
310
<React.Fragment>
311
<LegacyContextProvider>
312
<LegacyContextConsumer />
@@ -269,7 +317,6 @@ describe('InspectedElement', () => {
317
<ModernContext.Consumer>{value => null}</ModernContext.Consumer>
318
</ModernContext.Provider>
319
</React.Fragment>,
272
- container,
320
),
321
);
322
@@ -303,7 +350,7 @@ describe('InspectedElement', () => {
350
// from props like defaultSelectedElementID and it's easier to reset here than
351
// to read the TreeDispatcherContext and update the selected ID that way.
352
// We're testing the inspected values here, not the context wiring, so that's ok.
306
- utils.withErrorsOrWarningsIgnored(
353
+ withErrorsOrWarningsIgnored(
354
['An update to %s inside a test was not wrapped in act'],
355
() => {
356
testRendererInstance = TestRenderer.create(null, {
@@ -322,11 +369,7 @@ describe('InspectedElement', () => {
369
it('should poll for updates for the currently selected element', async () => {
370
const Example = () => null;
371
325
- const container = document.createElement('div');
326
- await utils.actAsync(
327
- () => legacyRender(<Example a={1} b="abc" />, container),
328
- false,
329
- );
372
+ await utils.actAsync(() => render(<Example a={1} b="abc" />), false);
373
374
let inspectedElement = await inspectElementAtIndex(0);
375
expect(inspectedElement.props).toMatchInlineSnapshot(`
@@ -336,10 +379,7 @@ describe('InspectedElement', () => {
379
}
380
`);
381
339
- await utils.actAsync(
340
- () => legacyRender(<Example a={2} b="def" />, container),
341
- false,
342
- );
382
+ await utils.actAsync(() => render(<Example a={2} b="def" />), false);
383
384
// TODO (cache)
385
// This test only passes if both the check-for-updates poll AND the test renderer.update() call are included below.
@@ -371,13 +411,11 @@ describe('InspectedElement', () => {
411
return null;
412
});
413
374
- const container = document.createElement('div');
414
await utils.actAsync(() =>
376
- legacyRender(
415
+ render(
416
<Wrapper>
417
<Target a={1} b="abc" />
418
</Wrapper>,
380
- container,
419
),
420
);
421
@@ -403,11 +441,10 @@ describe('InspectedElement', () => {
441
442
await utils.actAsync(
443
() =>
406
- legacyRender(
444
+ render(
445
<Wrapper>
446
<Target a={2} b="def" />
447
</Wrapper>,
410
- container,
448
),
449
false,
450
);
@@ -435,13 +472,11 @@ describe('InspectedElement', () => {
472
return null;
473
});
474
438
- const container = document.createElement('div');
475
await utils.actAsync(() =>
440
- legacyRender(
476
+ render(
477
<Wrapper>
478
<Target a={1} b="abc" />
479
</Wrapper>,
444
- container,
480
),
481
);
482
@@ -465,7 +500,7 @@ describe('InspectedElement', () => {
500
// The backend still thinks the most recently-inspected element is still cached,
501
// so the frontend needs to tell it to resend a full value.
502
// We can verify this by asserting that the component is re-rendered again.
468
- utils.withErrorsOrWarningsIgnored(
503
+ withErrorsOrWarningsIgnored(
504
['An update to %s inside a test was not wrapped in act'],
505
() => {
506
testRendererInstance = TestRenderer.create(null, {
@@ -503,9 +538,7 @@ describe('InspectedElement', () => {
538
return null;
539
});
540
506
- const container = document.createElement('div');
507
- const root = ReactDOMClient.createRoot(container);
508
- await utils.actAsync(() => root.render(<Target a={1} b="abc" />));
541
+ await utils.actAsync(() => render(<Target a={1} b="abc" />));
542
543
expect(targetRenderCount).toBe(1);
544
expect(console.error).toHaveBeenCalledTimes(1);
@@ -530,9 +563,8 @@ describe('InspectedElement', () => {
563
it('should support simple data types', async () => {
564
const Example = () => null;
565
533
- const container = document.createElement('div');
566
await utils.actAsync(() =>
535
- legacyRender(
567
+ render(
568
<Example
569
boolean_false={false}
570
boolean_true={true}
@@ -546,7 +578,6 @@ describe('InspectedElement', () => {
578
value_null={null}
579
value_undefined={undefined}
580
/>,
549
- container,
581
),
582
);
583
@@ -619,9 +650,8 @@ describe('InspectedElement', () => {
650
},
651
});
652
622
- const container = document.createElement('div');
653
await utils.actAsync(() =>
624
- legacyRender(
654
+ render(
655
<Example
656
anonymous_fn={instance.anonymousFunction}
657
array_buffer={arrayBuffer}
@@ -646,7 +676,6 @@ describe('InspectedElement', () => {
676
symbol={Symbol('symbol')}
677
typed_array={typedArray}
678
/>,
649
- container,
679
),
680
);
681
@@ -781,12 +810,8 @@ describe('InspectedElement', () => {
810
throw Error('Should not be consumed!');
811
}
812
784
- const container = document.createElement('div');
785
-
813
const iterable = generator();
787
- await utils.actAsync(() =>
788
- legacyRender(<Example prop={iterable} />, container),
789
- );
814
+ await utils.actAsync(() => render(<Example prop={iterable} />));
815
816
const inspectedElement = await inspectElementAtIndex(0);
817
expect(inspectedElement.props).toMatchInlineSnapshot(`
@@ -807,10 +832,7 @@ describe('InspectedElement', () => {
832
object.number = 123;
833
object.boolean = true;
834
810
- const container = document.createElement('div');
811
- await utils.actAsync(() =>
812
- legacyRender(<Example object={object} />, container),
813
- );
835
+ await utils.actAsync(() => render(<Example object={object} />));
836
837
const inspectedElement = await inspectElementAtIndex(0);
838
expect(inspectedElement.props).toMatchInlineSnapshot(`
@@ -832,10 +854,7 @@ describe('InspectedElement', () => {
854
hasOwnProperty: true,
855
};
856
835
- const container = document.createElement('div');
836
- await utils.actAsync(() =>
837
- legacyRender(<Example object={object} />, container),
838
- );
857
+ await utils.actAsync(() => render(<Example object={object} />));
858
859
const inspectedElement = await inspectElementAtIndex(0);
860
@@ -869,10 +888,7 @@ describe('InspectedElement', () => {
888
889
const Example = () => null;
890
872
- const container = document.createElement('div');
873
- await utils.actAsync(() =>
874
- legacyRender(<Example data={new CustomData()} />, container),
875
- );
891
+ await utils.actAsync(() => render(<Example data={new CustomData()} />));
892
893
const inspectedElement = await inspectElementAtIndex(0);
894
expect(inspectedElement.props).toMatchInlineSnapshot(`
@@ -948,10 +964,7 @@ describe('InspectedElement', () => {
964
},
965
});
966
951
- const container = document.createElement('div');
952
- await utils.actAsync(() =>
953
- legacyRender(<Example object={object} />, container),
954
- );
967
+ await utils.actAsync(() => render(<Example object={object} />));
968
969
const inspectedElement = await inspectElementAtIndex(0);
970
expect(inspectedElement.props).toMatchInlineSnapshot(`
@@ -1003,10 +1016,8 @@ describe('InspectedElement', () => {
1016
},
1017
);
1018
const Example = ({data}) => null;
1006
- const container = document.createElement('div');
1007
- await utils.actAsync(() =>
1008
- legacyRender(<Example data={testData} />, container),
1009
- );
1019
+
1020
+ await utils.actAsync(() => render(<Example data={testData} />));
1021
1022
const inspectedElement = await inspectElementAtIndex(0);
1023
expect(inspectedElement.props).toMatchInlineSnapshot(`
@@ -1034,9 +1045,8 @@ describe('InspectedElement', () => {
1045
return state.foo.bar.baz;
1046
};
1047
1037
- const container = document.createElement('div');
1048
await utils.actAsync(() =>
1039
- legacyRender(
1049
+ render(
1050
<Example
1051
nestedObject={{
1052
a: {
@@ -1052,7 +1062,6 @@ describe('InspectedElement', () => {
1062
},
1063
}}
1064
/>,
1055
- container,
1065
),
1066
);
1067
@@ -1200,13 +1209,11 @@ describe('InspectedElement', () => {
1209
it('should dehydrate complex nested values when requested', async () => {
1210
const Example = () => null;
1211
1203
- const container = document.createElement('div');
1212
await utils.actAsync(() =>
1205
- legacyRender(
1213
+ render(
1214
<Example
1215
set_of_sets={new Set([new Set([1, 2, 3]), new Set(['a', 'b', 'c'])])}
1216
/>,
1209
- container,
1217
),
1218
);
1219
@@ -1265,9 +1272,8 @@ describe('InspectedElement', () => {
1272
it('should include updates for nested values that were previously hydrated', async () => {
1273
const Example = () => null;
1274
1268
- const container = document.createElement('div');
1275
await utils.actAsync(() =>
1270
- legacyRender(
1276
+ render(
1277
<Example
1278
nestedObject={{
1279
a: {
@@ -1287,7 +1293,6 @@ describe('InspectedElement', () => {
1293
},
1294
}}
1295
/>,
1290
- container,
1296
),
1297
);
1298
@@ -1370,7 +1375,7 @@ describe('InspectedElement', () => {
1375
1376
await TestRendererAct(async () => {
1377
await TestUtilsAct(async () => {
1373
- legacyRender(
1378
+ render(
1379
<Example
1380
nestedObject={{
1381
a: {
@@ -1390,7 +1395,6 @@ describe('InspectedElement', () => {
1395
},
1396
}}
1397
/>,
1393
- container,
1398
);
1399
});
1400
});
@@ -1427,9 +1431,8 @@ describe('InspectedElement', () => {
1431
it('should return a full update if a path is inspected for an object that has other pending changes', async () => {
1432
const Example = () => null;
1433
1430
- const container = document.createElement('div');
1434
await utils.actAsync(() =>
1432
- legacyRender(
1435
+ render(
1436
<Example
1437
nestedObject={{
1438
a: {
@@ -1449,7 +1452,6 @@ describe('InspectedElement', () => {
1452
},
1453
}}
1454
/>,
1452
- container,
1455
),
1456
);
1457
@@ -1507,7 +1509,7 @@ describe('InspectedElement', () => {
1509
1510
await TestRendererAct(async () => {
1511
await TestUtilsAct(async () => {
1510
- legacyRender(
1512
+ render(
1513
<Example
1514
nestedObject={{
1515
a: {
@@ -1527,7 +1529,6 @@ describe('InspectedElement', () => {
1529
},
1530
}}
1531
/>,
1530
- container,
1532
);
1533
});
1534
});
@@ -1561,9 +1562,8 @@ describe('InspectedElement', () => {
1562
it('should not tear if hydration is requested after an update', async () => {
1563
const Example = () => null;
1564
1564
- const container = document.createElement('div');
1565
await utils.actAsync(() =>
1566
- legacyRender(
1566
+ render(
1567
<Example
1568
nestedObject={{
1569
value: 1,
@@ -1575,7 +1575,6 @@ describe('InspectedElement', () => {
1575
},
1576
}}
1577
/>,
1578
- container,
1578
),
1579
);
1580
@@ -1610,7 +1609,7 @@ describe('InspectedElement', () => {
1609
`);
1610
1611
await TestUtilsAct(async () => {
1613
- legacyRender(
1612
+ render(
1613
<Example
1614
nestedObject={{
1615
value: 2,
@@ -1622,7 +1621,6 @@ describe('InspectedElement', () => {
1621
},
1622
}}
1623
/>,
1625
- container,
1624
);
1625
});
1626
@@ -1643,17 +1641,16 @@ describe('InspectedElement', () => {
1641
`);
1642
});
1643
1646
- it('should inspect hooks for components that only use context', async () => {
1644
+ // TODO(hoxyq): Enable this test for versions ~18, currently broken
1645
+ // @reactVersion <= 18.2
1646
+ xit('should inspect hooks for components that only use context (legacy render)', async () => {
1647
const Context = React.createContext(true);
1648
const Example = () => {
1649
const value = React.useContext(Context);
1650
return value;
1651
};
1652
1653
- const container = document.createElement('div');
1654
- await utils.actAsync(() =>
1655
- legacyRender(<Example a={1} b="abc" />, container),
1656
- );
1653
+ await utils.actAsync(() => legacyRender(<Example a={1} b="abc" />));
1654
1655
const inspectedElement = await inspectElementAtIndex(0);
1656
expect(inspectedElement).toMatchInlineSnapshot(`
@@ -1687,6 +1684,47 @@ describe('InspectedElement', () => {
1684
`);
1685
});
1686
1687
+ it('should inspect hooks for components that only use context (createRoot)', async () => {
1688
+ const Context = React.createContext(true);
1689
+ const Example = () => {
1690
+ const value = React.useContext(Context);
1691
+ return value;
1692
+ };
1693
+
1694
+ await utils.actAsync(() => modernRender(<Example a={1} b="abc" />));
1695
+
1696
+ const inspectedElement = await inspectElementAtIndex(0);
1697
+ expect(inspectedElement).toMatchInlineSnapshot(`
1698
+ {
1699
+ "context": null,
1700
+ "events": undefined,
1701
+ "hooks": [
1702
+ {
1703
+ "hookSource": {
1704
+ "columnNumber": "removed by Jest serializer",
1705
+ "fileName": "react-devtools-shared/src/__tests__/inspectedElement-test.js",
1706
+ "functionName": "Example",
1707
+ "lineNumber": "removed by Jest serializer",
1708
+ },
1709
+ "id": null,
1710
+ "isStateEditable": false,
1711
+ "name": "Context",
1712
+ "subHooks": [],
1713
+ "value": true,
1714
+ },
1715
+ ],
1716
+ "id": 2,
1717
+ "owners": null,
1718
+ "props": {
1719
+ "a": 1,
1720
+ "b": "abc",
1721
+ },
1722
+ "rootType": "createRoot()",
1723
+ "state": null,
1724
+ }
1725
+ `);
1726
+ });
1727
+
1728
it('should enable inspected values to be stored as global variables', async () => {
1729
const Example = () => null;
1730
@@ -1702,12 +1740,7 @@ describe('InspectedElement', () => {
1740
},
1741
};
1742
1705
- await utils.actAsync(() =>
1706
- legacyRender(
1707
- <Example nestedObject={nestedObject} />,
1708
- document.createElement('div'),
1709
- ),
1710
- );
1743
+ await utils.actAsync(() => render(<Example nestedObject={nestedObject} />));
1744
1745
let storeAsGlobal: StoreAsGlobal = ((null: any): StoreAsGlobal);
1746
@@ -1761,12 +1794,7 @@ describe('InspectedElement', () => {
1794
},
1795
};
1796
1764
- await utils.actAsync(() =>
1765
- legacyRender(
1766
- <Example nestedObject={nestedObject} />,
1767
- document.createElement('div'),
1768
- ),
1769
- );
1797
+ await utils.actAsync(() => render(<Example nestedObject={nestedObject} />));
1798
1799
let copyPath: CopyInspectedElementPath =
1800
((null: any): CopyInspectedElementPath);
@@ -1837,7 +1865,7 @@ describe('InspectedElement', () => {
1865
const bigInt = BigInt(123); // eslint-disable-line no-undef
1866
1867
await utils.actAsync(() =>
1840
- legacyRender(
1868
+ render(
1869
<Example
1870
arrayBuffer={arrayBuffer}
1871
dataView={dataView}
@@ -1849,7 +1877,6 @@ describe('InspectedElement', () => {
1877
immutable={immutable}
1878
bigInt={bigInt}
1879
/>,
1852
- document.createElement('div'),
1880
),
1881
);
1882
@@ -1902,8 +1929,6 @@ describe('InspectedElement', () => {
1929
});
1930
1931
it('should display complex values of useDebugValue', async () => {
1905
- const container = document.createElement('div');
1906
-
1932
function useDebuggableHook() {
1933
React.useDebugValue({foo: 2});
1934
React.useState(1);
@@ -1914,9 +1939,7 @@ describe('InspectedElement', () => {
1939
return null;
1940
}
1941
1917
- await utils.actAsync(() =>
1918
- legacyRender(<DisplayedComplexValue />, container),
1919
- );
1942
+ await utils.actAsync(() => render(<DisplayedComplexValue />));
1943
1944
const {hooks} = await inspectElementAtIndex(0);
1945
expect(hooks).toMatchInlineSnapshot(`
@@ -1967,10 +1990,7 @@ describe('InspectedElement', () => {
1990
},
1991
);
1992
1970
- const container = document.createElement('div');
1971
- await utils.actAsync(() =>
1972
- legacyRender(<Example proxy={proxy} />, container),
1973
- );
1993
+ await utils.actAsync(() => render(<Example proxy={proxy} />));
1994
1995
const inspectedElement = await inspectElementAtIndex(0);
1996
@@ -1994,12 +2014,13 @@ describe('InspectedElement', () => {
2014
`);
2015
});
2016
2017
+ // TODO(hoxyq): Enable this test for versions ~18, currently broken
2018
// Regression test for github.com/facebook/react/issues/22099
1998
- it('should not error when an unchanged component is re-inspected after component filters changed', async () => {
2019
+ // @reactVersion <= 18.2
2020
+ xit('should not error when an unchanged component is re-inspected after component filters changed (legacy render)', async () => {
2021
const Example = () => <div />;
2022
2001
- const container = document.createElement('div');
2002
- await utils.actAsync(() => legacyRender(<Example />, container));
2023
+ await utils.actAsync(() => legacyRender(<Example />));
2024
2025
// Select/inspect element
2026
let inspectedElement = await inspectElementAtIndex(0);
@@ -2018,7 +2039,7 @@ describe('InspectedElement', () => {
2039
2040
await utils.actAsync(async () => {
2041
// Ignore transient warning this causes
2021
- utils.withErrorsOrWarningsIgnored(['No element found with id'], () => {
2042
+ withErrorsOrWarningsIgnored(['No element found with id'], () => {
2043
store.componentFilters = [];
2044
2045
// Flush events to the renderer.
@@ -2030,7 +2051,7 @@ describe('InspectedElement', () => {
2051
// from props like defaultSelectedElementID and it's easier to reset here than
2052
// to read the TreeDispatcherContext and update the selected ID that way.
2053
// We're testing the inspected values here, not the context wiring, so that's ok.
2033
- utils.withErrorsOrWarningsIgnored(
2054
+ withErrorsOrWarningsIgnored(
2055
['An update to %s inside a test was not wrapped in act'],
2056
() => {
2057
testRendererInstance = TestRenderer.create(null, {
@@ -2055,7 +2076,69 @@ describe('InspectedElement', () => {
2076
`);
2077
});
2078
2058
- it('should display the root type for ReactDOM.hydrate', async () => {
2079
+ // Regression test for github.com/facebook/react/issues/22099
2080
+ it('should not error when an unchanged component is re-inspected after component filters changed (createRoot)', async () => {
2081
+ const Example = () => <div />;
2082
+
2083
+ await utils.actAsync(() => modernRender(<Example />));
2084
+
2085
+ // Select/inspect element
2086
+ let inspectedElement = await inspectElementAtIndex(0);
2087
+ expect(inspectedElement).toMatchInlineSnapshot(`
2088
+ {
2089
+ "context": null,
2090
+ "events": undefined,
2091
+ "hooks": null,
2092
+ "id": 2,
2093
+ "owners": null,
2094
+ "props": {},
2095
+ "rootType": "createRoot()",
2096
+ "state": null,
2097
+ }
2098
+ `);
2099
+
2100
+ await utils.actAsync(async () => {
2101
+ // Ignore transient warning this causes
2102
+ withErrorsOrWarningsIgnored(['No element found with id'], () => {
2103
+ store.componentFilters = [];
2104
+
2105
+ // Flush events to the renderer.
2106
+ jest.runOnlyPendingTimers();
2107
+ });
2108
+ }, false);
2109
+
2110
+ // HACK: Recreate TestRenderer instance because we rely on default state values
2111
+ // from props like defaultSelectedElementID and it's easier to reset here than
2112
+ // to read the TreeDispatcherContext and update the selected ID that way.
2113
+ // We're testing the inspected values here, not the context wiring, so that's ok.
2114
+ withErrorsOrWarningsIgnored(
2115
+ ['An update to %s inside a test was not wrapped in act'],
2116
+ () => {
2117
+ testRendererInstance = TestRenderer.create(null, {
2118
+ isConcurrent: true,
2119
+ });
2120
+ },
2121
+ );
2122
+
2123
+ // Select/inspect the same element again
2124
+ inspectedElement = await inspectElementAtIndex(0);
2125
+ expect(inspectedElement).toMatchInlineSnapshot(`
2126
+ {
2127
+ "context": null,
2128
+ "events": undefined,
2129
+ "hooks": null,
2130
+ "id": 2,
2131
+ "owners": null,
2132
+ "props": {},
2133
+ "rootType": "createRoot()",
2134
+ "state": null,
2135
+ }
2136
+ `);
2137
+ });
2138
+
2139
+ // TODO(hoxyq): Enable this test for versions ~18, currently broken
2140
+ // @reactVersion <= 18.2
2141
+ xit('should display the root type for ReactDOM.hydrate', async () => {
2142
const Example = () => <div />;
2143
2144
await utils.actAsync(() => {
@@ -2073,12 +2156,13 @@ describe('InspectedElement', () => {
2156
expect(inspectedElement.rootType).toMatchInlineSnapshot(`"hydrate()"`);
2157
});
2158
2076
- it('should display the root type for ReactDOM.render', async () => {
2159
+ // TODO(hoxyq): Enable this test for versions ~18, currently broken
2160
+ // @reactVersion <= 18.2
2161
+ xit('should display the root type for ReactDOM.render', async () => {
2162
const Example = () => <div />;
2163
2164
await utils.actAsync(() => {
2080
- const container = document.createElement('div');
2081
- legacyRender(<Example />, container);
2165
+ legacyRender(<Example />);
2166
}, false);
2167
2168
const inspectedElement = await inspectElementAtIndex(0);
@@ -2126,8 +2210,7 @@ describe('InspectedElement', () => {
2210
};
2211
2212
await utils.actAsync(() => {
2129
- const container = document.createElement('div');
2130
- ReactDOMClient.createRoot(container).render(<Example />);
2213
+ render(<Example />);
2214
}, false);
2215
2216
shouldThrow = true;
@@ -2148,10 +2231,7 @@ describe('InspectedElement', () => {
2231
return count;
2232
};
2233
2151
- const container = document.createElement('div');
2152
- await utils.actAsync(() =>
2153
- legacyRender(<Example a={1} b="abc" />, container),
2154
- );
2234
+ await utils.actAsync(() => render(<Example a={1} b="abc" />));
2235
2236
await inspectElementAtIndex(0);
2237
@@ -2187,10 +2267,7 @@ describe('InspectedElement', () => {
2267
return count;
2268
});
2269
2190
- const container = document.createElement('div');
2191
- await utils.actAsync(() =>
2192
- legacyRender(<Example a={1} b="abc" />, container),
2193
- );
2270
+ await utils.actAsync(() => render(<Example a={1} b="abc" />));
2271
2272
await inspectElementAtIndex(0);
2273
@@ -2226,10 +2303,7 @@ describe('InspectedElement', () => {
2303
return count;
2304
});
2305
2229
- const container = document.createElement('div');
2230
- await utils.actAsync(() =>
2231
- legacyRender(<Example a={1} b="abc" />, container),
2232
- );
2306
+ await utils.actAsync(() => render(<Example a={1} b="abc" />));
2307
2308
await inspectElementAtIndex(0);
2309
@@ -2269,10 +2343,7 @@ describe('InspectedElement', () => {
2343
}
2344
}
2345
2272
- const container = document.createElement('div');
2273
- await utils.actAsync(() =>
2274
- legacyRender(<Example a={1} b="abc" />, container),
2275
- );
2346
+ await utils.actAsync(() => render(<Example a={1} b="abc" />));
2347
2348
await inspectElementAtIndex(0);
2349
@@ -2334,12 +2405,8 @@ describe('InspectedElement', () => {
2405
return null;
2406
};
2407
2337
- const container = document.createElement('div');
2338
-
2408
await withErrorsOrWarningsIgnored(['test-only: '], async () => {
2340
- await utils.actAsync(() =>
2341
- legacyRender(<Example repeatWarningCount={1} />, container),
2342
- );
2409
+ await utils.actAsync(() => render(<Example repeatWarningCount={1} />));
2410
});
2411
2412
const data = await getErrorsAndWarningsForElementAtIndex(0);
@@ -2371,11 +2438,8 @@ describe('InspectedElement', () => {
2438
return null;
2439
};
2440
2374
- const container = document.createElement('div');
2375
- await utils.withErrorsOrWarningsIgnored(['test-only:'], async () => {
2376
- await utils.actAsync(() =>
2377
- legacyRender(<Example repeatWarningCount={1} />, container),
2378
- );
2441
+ await withErrorsOrWarningsIgnored(['test-only:'], async () => {
2442
+ await utils.actAsync(() => render(<Example repeatWarningCount={1} />));
2443
});
2444
const data = await getErrorsAndWarningsForElementAtIndex(0);
2445
expect(data).toMatchInlineSnapshot(`
@@ -2407,11 +2471,8 @@ describe('InspectedElement', () => {
2471
return null;
2472
};
2473
2410
- const container = document.createElement('div');
2411
- await utils.withErrorsOrWarningsIgnored(['test-only:'], async () => {
2412
- await utils.actAsync(() =>
2413
- legacyRender(<Example repeatWarningCount={1} />, container),
2414
- );
2474
+ await withErrorsOrWarningsIgnored(['test-only:'], async () => {
2475
+ await utils.actAsync(() => render(<Example repeatWarningCount={1} />));
2476
});
2477
2478
const data = await getErrorsAndWarningsForElementAtIndex(0);
@@ -2444,11 +2505,8 @@ describe('InspectedElement', () => {
2505
return null;
2506
};
2507
2447
- const container = document.createElement('div');
2448
- await utils.withErrorsOrWarningsIgnored(['test-only:'], async () => {
2449
- await utils.actAsync(() =>
2450
- legacyRender(<Example repeatWarningCount={1} />, container),
2451
- );
2508
+ await withErrorsOrWarningsIgnored(['test-only:'], async () => {
2509
+ await utils.actAsync(() => render(<Example repeatWarningCount={1} />));
2510
});
2511
2512
const data = await getErrorsAndWarningsForElementAtIndex(0);
@@ -2475,12 +2533,11 @@ describe('InspectedElement', () => {
2533
return [<div />];
2534
};
2535
2478
- const container = document.createElement('div');
2479
- await utils.withErrorsOrWarningsIgnored(
2536
+ await withErrorsOrWarningsIgnored(
2537
['Warning: Each child in a list should have a unique "key" prop.'],
2538
async () => {
2539
await utils.actAsync(() =>
2483
- legacyRender(<Example repeatWarningCount={1} />, container),
2540
+ render(<Example repeatWarningCount={1} />),
2541
);
2542
},
2543
);
@@ -2507,11 +2564,8 @@ describe('InspectedElement', () => {
2564
return null;
2565
};
2566
2510
- const container = document.createElement('div');
2511
- await utils.withErrorsOrWarningsIgnored(['test-only:'], async () => {
2512
- await utils.actAsync(() =>
2513
- legacyRender(<Example repeatWarningCount={1} />, container),
2514
- );
2567
+ await withErrorsOrWarningsIgnored(['test-only:'], async () => {
2568
+ await utils.actAsync(() => render(<Example repeatWarningCount={1} />));
2569
});
2570
2571
const {
@@ -2538,15 +2592,13 @@ describe('InspectedElement', () => {
2592
return null;
2593
};
2594
2541
- const container = document.createElement('div');
2542
- await utils.withErrorsOrWarningsIgnored(['test-only:'], async () => {
2595
+ await withErrorsOrWarningsIgnored(['test-only:'], async () => {
2596
await utils.actAsync(() =>
2544
- legacyRender(
2597
+ render(
2598
<React.Fragment>
2599
<Example id={1} />
2600
<Example id={2} />
2601
</React.Fragment>,
2549
- container,
2602
),
2603
);
2604
});
@@ -2635,15 +2687,13 @@ describe('InspectedElement', () => {
2687
return null;
2688
};
2689
2638
- const container = document.createElement('div');
2639
- await utils.withErrorsOrWarningsIgnored(['test-only:'], async () => {
2690
+ await withErrorsOrWarningsIgnored(['test-only:'], async () => {
2691
await utils.actAsync(() =>
2641
- legacyRender(
2692
+ render(
2693
<React.Fragment>
2694
<Example id={1} />
2695
<Example id={2} />
2696
</React.Fragment>,
2646
- container,
2697
),
2698
);
2699
});
@@ -2726,7 +2776,9 @@ describe('InspectedElement', () => {
2776
});
2777
});
2778
2729
- it('inspecting nested renderers should not throw', async () => {
2779
+ // TODO(hoxyq): Enable this test for versions ~18, currently broken
2780
+ // @reactVersion <= 18.2
2781
+ xit('inspecting nested renderers should not throw (legacy render)', async () => {
2782
// Ignoring react art warnings
2783
jest.spyOn(console, 'error').mockImplementation(() => {});
2784
const ReactArt = require('react-art');
@@ -2749,7 +2801,7 @@ describe('InspectedElement', () => {
2801
}
2802
2803
await utils.actAsync(() => {
2752
- legacyRender(<App />, document.createElement('div'));
2804
+ legacyRender(<App />);
2805
});
2806
expect(store).toMatchInlineSnapshot(`
2807
[root]
@@ -2784,6 +2836,64 @@ describe('InspectedElement', () => {
2836
`);
2837
});
2838
2839
+ it('inspecting nested renderers should not throw (createRoot)', async () => {
2840
+ // Ignoring react art warnings
2841
+ jest.spyOn(console, 'error').mockImplementation(() => {});
2842
+ const ReactArt = require('react-art');
2843
+ const ArtSVGMode = require('art/modes/svg');
2844
+ const ARTCurrentMode = require('art/modes/current');
2845
+ store.componentFilters = [];
2846
+
2847
+ ARTCurrentMode.setCurrent(ArtSVGMode);
2848
+ const {Surface, Group} = ReactArt;
2849
+
2850
+ function Child() {
2851
+ return (
2852
+ <Surface width={1} height={1}>
2853
+ <Group />
2854
+ </Surface>
2855
+ );
2856
+ }
2857
+ function App() {
2858
+ return <Child />;
2859
+ }
2860
+
2861
+ await utils.actAsync(() => {
2862
+ modernRender(<App />);
2863
+ });
2864
+ expect(store).toMatchInlineSnapshot(`
2865
+ [root]
2866
+ ▾ <App>
2867
+ ▾ <Child>
2868
+ ▾ <Surface>
2869
+ <svg>
2870
+ [root]
2871
+ <Group>
2872
+ `);
2873
+
2874
+ const inspectedElement = await inspectElementAtIndex(4);
2875
+ expect(inspectedElement.owners).toMatchInlineSnapshot(`
2876
+ [
2877
+ {
2878
+ "compiledWithForget": false,
2879
+ "displayName": "Child",
2880
+ "hocDisplayNames": null,
2881
+ "id": 5,
2882
+ "key": null,
2883
+ "type": 5,
2884
+ },
2885
+ {
2886
+ "compiledWithForget": false,
2887
+ "displayName": "App",
2888
+ "hocDisplayNames": null,
2889
+ "id": 4,
2890
+ "key": null,
2891
+ "type": 5,
2892
+ },
2893
+ ]
2894
+ `);
2895
+ });
2896
+
2897
describe('error boundary', () => {
2898
it('can toggle error', async () => {
2899
class LocalErrorBoundary extends React.Component<any> {
@@ -2800,11 +2910,10 @@ describe('InspectedElement', () => {
2910
const Example = () => 'example';
2911
2912
await utils.actAsync(() =>
2803
- legacyRender(
2913
+ render(
2914
<LocalErrorBoundary>
2915
<Example />
2916
</LocalErrorBoundary>,
2807
- document.createElement('div'),
2917
),
2918
);
2919
@@ -2813,7 +2922,7 @@ describe('InspectedElement', () => {
2922
): any): number);
2923
const inspect = index => {
2924
// HACK: Recreate TestRenderer instance so we can inspect different elements
2816
- utils.withErrorsOrWarningsIgnored(
2925
+ withErrorsOrWarningsIgnored(
2926
['An update to %s inside a test was not wrapped in act'],
2927
() => {
2928
testRendererInstance = TestRenderer.create(null, {