main
js 136 lines 3.88 KB
Raw
1 /** @flow */
2
3 // This test harness mounts each test app as a separate root to test multi-root applications.
4
5 import semver from 'semver';
6
7 import {createElement} from 'react';
8 import {createRoot} from 'react-dom/client';
9
10 import DeeplyNestedComponents from './DeeplyNestedComponents';
11 import Iframe from './Iframe';
12 import EditableProps from './EditableProps';
13 import ElementTypes from './ElementTypes';
14 import Hydration from './Hydration';
15 import InspectableElements from './InspectableElements';
16 import ReactNativeWeb from './ReactNativeWeb';
17 import ToDoList from './ToDoList';
18 import Toggle from './Toggle';
19 import ErrorBoundaries from './ErrorBoundaries';
20 import PartiallyStrictApp from './PartiallyStrictApp';
21 import Segments from './Segments';
22 import SuspenseTree from './SuspenseTree';
23 import SearchableTable from './SearchableTable';
24 import ActivityTree from './ActivityTree';
25 import TraceUpdatesTest from './TraceUpdatesTest';
26 import {ignoreErrors, ignoreLogs, ignoreWarnings} from './console';
27
28 import './styles.css';
29
30 // DevTools intentionally tests compatibility with certain legacy APIs.
31 // Suppress their error messages in the local dev shell,
32 // because they might mask other more serious error messages.
33 ignoreErrors([
34 'Warning: Legacy context API',
35 'Warning: Unsafe lifecycle methods',
36 'Warning: %s is deprecated in StrictMode.', // findDOMNode
37 'Warning: ReactDOM.render was removed in React 19',
38 'Warning: react-test-renderer is deprecated',
39 // Ignore prefixed and not prefixed since I don't know which
40 // React versions are being tested by this code.
41 'Legacy context API',
42 'Unsafe lifecycle methods',
43 '%s is deprecated in StrictMode.', // findDOMNode
44 'ReactDOM.render was removed in React 19',
45 'react-test-renderer is deprecated',
46 ]);
47 ignoreWarnings([
48 'Warning: componentWillReceiveProps has been renamed',
49 'componentWillReceiveProps has been renamed',
50 ]);
51 ignoreLogs([]);
52
53 const unmountFunctions: Array<() => void | boolean> = [];
54
55 function createContainer() {
56 const container = document.createElement('div');
57
58 (document.body as any as HTMLBodyElement).appendChild(container);
59
60 return container;
61 }
62
63 function mountApp(App: () => React$Node) {
64 const container = createContainer();
65
66 const root = createRoot(container);
67 root.render(createElement(App));
68
69 unmountFunctions.push(() => root.unmount());
70 }
71
72 // $FlowFixMe[missing-local-annot]
73 function mountStrictApp(App) {
74 function StrictRoot() {
75 return createElement(App);
76 }
77
78 const container = createContainer();
79
80 const root = createRoot(container, {unstable_strictMode: true});
81 root.render(createElement(StrictRoot));
82
83 unmountFunctions.push(() => root.unmount());
84 }
85
86 function mountLegacyApp(App: () => React$Node) {
87 // $FlowFixMe[prop-missing]: These are removed in 19.
88 const {render, unmountComponentAtNode} = require('react-dom');
89
90 function LegacyRender() {
91 return createElement(App);
92 }
93
94 const container = createContainer();
95
96 // $FlowFixMe[not-a-function]: These are removed in 19.
97 render(createElement(LegacyRender), container);
98
99 // $FlowFixMe[not-a-function]: These are removed in 19.
100 unmountFunctions.push(() => unmountComponentAtNode(container));
101 }
102
103 const shouldRenderLegacy = semver.lte(
104 process.env.E2E_APP_REACT_VERSION,
105 '18.2.0',
106 );
107 function mountTestApp() {
108 mountStrictApp(ToDoList);
109 mountApp(InspectableElements);
110 mountApp(Hydration);
111 mountApp(ElementTypes);
112 mountApp(EditableProps);
113 mountApp(ReactNativeWeb);
114 mountApp(Toggle);
115 mountApp(ErrorBoundaries);
116 mountApp(SuspenseTree);
117 mountApp(SearchableTable);
118 mountApp(DeeplyNestedComponents);
119 mountApp(Iframe);
120 mountApp(ActivityTree);
121 mountApp(TraceUpdatesTest);
122 mountApp(Segments);
123
124 if (shouldRenderLegacy) {
125 mountLegacyApp(PartiallyStrictApp);
126 }
127 }
128
129 function unmountTestApp() {
130 unmountFunctions.forEach(fn => fn());
131 }
132
133 mountTestApp();
134
135 window.parent.mountTestApp = mountTestApp;
136 window.parent.unmountTestApp = unmountTestApp;