@samitouri / QOS-React-1 / commits / bfdc12c191

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, {