diff --git a/test/regression/14.9.html b/test/regression/14.9.html
new file mode 100644
index 0000000000..d5e3319106
--- /dev/null
+++ b/test/regression/14.9.html
@@ -0,0 +1,39 @@
+
+
+
+
+ React 16.0
+
+
+
+
+
+
+
+
+
+
+
+
+ If you are seeing this message, you are likely viewing this file using the file protocol which does not support cross origin requests.
+
+ Use a web server like serve instead:
+
+ npm install -g pushstate-server
+ pushstate-server .
+ open http://localhost:9000/16.html
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/regression/15.6.html b/test/regression/15.6.html
new file mode 100644
index 0000000000..80e2f44ee4
--- /dev/null
+++ b/test/regression/15.6.html
@@ -0,0 +1,39 @@
+
+
+
+
+ React 16.0
+
+
+
+
+
+
+
+
+
+
+
+
+ If you are seeing this message, you are likely viewing this file using the file protocol which does not support cross origin requests.
+
+ Use a web server like serve instead:
+
+ npm install -g pushstate-server
+ pushstate-server .
+ open http://localhost:9000/16.html
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/regression/16.0.html b/test/regression/16.0.html
new file mode 100644
index 0000000000..bc12dbc50b
--- /dev/null
+++ b/test/regression/16.0.html
@@ -0,0 +1,39 @@
+
+
+
+
+ React 16.0
+
+
+
+
+
+
+
+
+
+
+
+
+ If you are seeing this message, you are likely viewing this file using the file protocol which does not support cross origin requests.
+
+ Use a web server like serve instead:
+
+ npm install -g pushstate-server
+ pushstate-server .
+ open http://localhost:9000/16.html
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/regression/16.1.html b/test/regression/16.1.html
new file mode 100644
index 0000000000..17074b7b79
--- /dev/null
+++ b/test/regression/16.1.html
@@ -0,0 +1,39 @@
+
+
+
+
+ React 16.1
+
+
+
+
+
+
+
+
+
+
+
+
+ If you are seeing this message, you are likely viewing this file using the file protocol which does not support cross origin requests.
+
+ Use a web server like serve instead:
+
+ npm install -g pushstate-server
+ pushstate-server .
+ open http://localhost:9000/16.html
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/regression/16.2.html b/test/regression/16.2.html
new file mode 100644
index 0000000000..b1d3a47c4f
--- /dev/null
+++ b/test/regression/16.2.html
@@ -0,0 +1,39 @@
+
+
+
+
+ React 16.2
+
+
+
+
+
+
+
+
+
+
+
+
+ If you are seeing this message, you are likely viewing this file using the file protocol which does not support cross origin requests.
+
+ Use a web server like serve instead:
+
+ npm install -g pushstate-server
+ pushstate-server .
+ open http://localhost:9000/16.html
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/regression/16.3.html b/test/regression/16.3.html
new file mode 100644
index 0000000000..a934118c49
--- /dev/null
+++ b/test/regression/16.3.html
@@ -0,0 +1,39 @@
+
+
+
+
+ React 16.3
+
+
+
+
+
+
+
+
+
+
+
+
+ If you are seeing this message, you are likely viewing this file using the file protocol which does not support cross origin requests.
+
+ Use a web server like serve instead:
+
+ npm install -g pushstate-server
+ pushstate-server .
+ open http://localhost:9000/16.html
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/regression/16.4.html b/test/regression/16.4.html
new file mode 100644
index 0000000000..82fd91bd19
--- /dev/null
+++ b/test/regression/16.4.html
@@ -0,0 +1,39 @@
+
+
+
+
+ React 16.4
+
+
+
+
+
+
+
+
+
+
+
+
+ If you are seeing this message, you are likely viewing this file using the file protocol which does not support cross origin requests.
+
+ Use a web server like serve instead:
+
+ npm install -g pushstate-server
+ pushstate-server .
+ open http://localhost:9000/16.html
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/regression/16.5.html b/test/regression/16.5.html
new file mode 100644
index 0000000000..c4246a798f
--- /dev/null
+++ b/test/regression/16.5.html
@@ -0,0 +1,41 @@
+
+
+
+
+ React 16.5
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ If you are seeing this message, you are likely viewing this file using the file protocol which does not support cross origin requests.
+
+ Use a web server like serve instead:
+
+ npm install -g pushstate-server
+ pushstate-server .
+ open http://localhost:9000/16.html
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/regression/16.6.html b/test/regression/16.6.html
new file mode 100644
index 0000000000..3aa98a5e58
--- /dev/null
+++ b/test/regression/16.6.html
@@ -0,0 +1,42 @@
+
+
+
+
+ React 16.6
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ If you are seeing this message, you are likely viewing this file using the file protocol which does not support cross origin requests.
+
+ Use a web server like serve instead:
+
+ npm install -g pushstate-server
+ pushstate-server .
+ open http://localhost:9000/16.html
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/regression/16.7.html b/test/regression/16.7.html
new file mode 100644
index 0000000000..01d46cc1d5
--- /dev/null
+++ b/test/regression/16.7.html
@@ -0,0 +1,42 @@
+
+
+
+
+ React 16.7
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ If you are seeing this message, you are likely viewing this file using the file protocol which does not support cross origin requests.
+
+ Use a web server like serve instead:
+
+ npm install -g pushstate-server
+ pushstate-server .
+ open http://localhost:9000/16.html
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/regression/index.html b/test/regression/index.html
new file mode 100644
index 0000000000..d56f1434ac
--- /dev/null
+++ b/test/regression/index.html
@@ -0,0 +1,20 @@
+
+
+
+
+ React 16
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/regression/shared.js b/test/regression/shared.js
new file mode 100644
index 0000000000..6f4af22597
--- /dev/null
+++ b/test/regression/shared.js
@@ -0,0 +1,265 @@
+/* eslint-disable no-fallthrough, react/react-in-jsx-scope, react/jsx-no-undef */
+/* global React ReactCache ReactDOM SchedulerTracing ScheduleTracing */
+
+const apps = [];
+
+const pieces = React.version.split('.');
+const major = pieces[0] === '0' ? parseInt(pieces[1], 10) : parseInt(pieces[0], 10);
+const minor = pieces[0] === '0' ? parseInt(pieces[2], 10) : parseInt(pieces[1], 10);
+
+// Convenience wrapper to organize API features in DevTools.
+function Feature({ children, label, version }) {
+ return (
+
+
+ {label}
+ {version}
+
+ {children}
+
+ );
+}
+
+// Simplify interaction tracing for tests below.
+let trace = null;
+if (typeof SchedulerTracing !== 'undefined') {
+ trace = SchedulerTracing.unstable_trace;
+} else if (typeof ScheduleTracing !== 'undefined') {
+ trace = ScheduleTracing.unstable_trace;
+} else {
+ trace = (_, __, callback) => callback();
+}
+
+// https://github.com/facebook/react/blob/master/CHANGELOG.md
+switch (major) {
+ case 16:
+ switch (minor) {
+ case 7:
+ // Hooks
+ function Hooks() {
+ const [count, setCount] = React.useState(0);
+ const incrementCount = React.useCallback(
+ () => setCount(count + 1),
+ [count]
+ );
+ return (
+
+ count: {count} increment
+
+ );
+ }
+ apps.push(
+
+
+
+ );
+ case 6:
+ // memo
+ function LabelComponent({label}) {
+ return {label} ;
+ }
+ const AnonymousMemoized = React.memo(({label}) => {label} );
+ const Memoized = React.memo(LabelComponent);
+ const CustomMemoized = React.memo(LabelComponent);
+ CustomMemoized.displayName = 'MemoizedLabelFunction';
+ apps.push(
+
+
+
+
+
+ );
+
+ // Suspense
+ const loadResource = ([text, ms]) => {
+ return new Promise((resolve, reject) => {
+ setTimeout(() => {
+ resolve(text);
+ }, ms);
+ });
+ };
+ const getResourceKey = ([text, ms]) => text;
+ const Resource = ReactCache.unstable_createResource(loadResource, getResourceKey);
+ class Suspending extends React.Component {
+ state = {useSuspense: false};
+ useSuspense = () => this.setState({useSuspense: true});
+ render() {
+ if (this.state.useSuspense) {
+ const text = Resource.read(['loaded', 2000]);
+ return text;
+ } else {
+ return (
+
+ load data
+
+ );
+ }
+ }
+ }
+ apps.push(
+
+ loading...}>
+
+
+
+ );
+ case 5:
+ case 4:
+ // unstable_Profiler
+ class ProfilerChild extends React.Component {
+ state = {count: 0};
+ incrementCount = () =>
+ this.setState(prevState => ({count: prevState.count + 1}));
+ render() {
+ return (
+
+ count: {this.state.count} increment
+
+ );
+ }
+ }
+ const onRender = (...args) => console.log('onRender()', ...args);
+ const Profiler = React.unstable_Profiler || React.Profiler;
+ apps.push(
+
+
+
+
+
+ );
+ case 3:
+ // createContext()
+ const LocaleContext = React.createContext();
+ LocaleContext.displayName = 'LocaleContext';
+ const ThemeContext = React.createContext();
+ apps.push(
+
+
+
+ {theme => (
+ theme: {theme}
+ )}
+
+
+
+
+ {locale => (
+ locale: {locale}
+ )}
+
+
+
+ );
+
+ // forwardRef()
+ const AnonymousFunction = React.forwardRef((props, ref) => (
+ {props.children}
+ ));
+ const NamedFunction = React.forwardRef(function named(props, ref) {
+ return (
+ {props.children}
+ );
+ });
+ const CustomName = React.forwardRef((props, ref) => (
+ {props.children}
+ ));
+ CustomName.displayName = 'CustomNameForwardRef';
+ apps.push(
+
+ AnonymousFunction
+ NamedFunction
+ CustomName
+
+ );
+
+ // StrictMode
+ class StrictModeChild extends React.Component {
+ render() {
+ return 'StrictModeChild';
+ }
+ }
+ apps.push(
+
+
+
+
+
+ );
+
+ // unstable_AsyncMode (later renamed to unstable_ConcurrentMode, then ConcurrentMode)
+ const ConcurrentMode = React.ConcurrentMode || React.unstable_ConcurrentMode || React.unstable_AsyncMode;
+ apps.push(
+
+
+ unstable_AsyncMode was added in 16.3, renamed to unstable_ConcurrentMode in 16.5, and then renamed to ConcurrentMode in 16.7
+
+
+ );
+ case 2:
+
+ // Fragment
+ apps.push(
+
+
+ one
+ two
+
+
+ );
+ case 1:
+ case 0:
+ }
+ break;
+ case 15:
+ break;
+ case 14:
+ break;
+}
+
+// Simple stateful app shared by all React versions
+class SimpleApp extends React.Component {
+ state = {count: 0};
+ incrementCount = () => {
+ const updaterFn = prevState => ({count: prevState.count + 1});
+ trace(
+ 'Updating count',
+ performance.now(),
+ () => this.setState(updaterFn)
+ );
+ };
+ render() {
+ const {count} = this.state;
+ return (
+
+ {count % 2 === 0 ? (
+ count: {count} (even)
+ ) : (
+ count: {count}
+ )} increment
+
+ );
+ }
+}
+apps.push(
+
+
+
+);
+
+// This component, with the version prop, helps organize DevTools at a glance.
+function TopLevelWrapperForDevTools({ version }) {
+ return (
+
+
React {version}
+ {apps}
+
+ );
+}
+TopLevelWrapperForDevTools.displayName = 'React';
+
+ReactDOM.render(
+ ,
+ document.getElementById('root')
+);
diff --git a/test/regression/styles.css b/test/regression/styles.css
new file mode 100644
index 0000000000..155eb3bb3a
--- /dev/null
+++ b/test/regression/styles.css
@@ -0,0 +1,33 @@
+body {
+ font-family: sans-serif;
+ font-size: 12px;
+}
+
+h1 {
+ margin: 0;
+ font-size: 20px;
+}
+
+h2 {
+ margin: 1rem 0 0;
+}
+
+iframe {
+ border: 1px solid #ddd;
+ border-radius: 0.5rem;
+}
+
+.Feature {
+ margin: 1rem 0;
+ border-bottom: 1px solid #eee;
+ padding-bottom: 1rem;
+}
+.FeatureHeader {
+ font-size: 16px;
+ margin-bottom: 0.5rem;
+}
+.FeatureCode {
+ background-color: #eee;
+ padding: 0.25rem;
+ border-radius: 0.25rem;
+}
\ No newline at end of file