Skip to content

[DevTools] e2e Regression Testing App #24619

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions packages/react-devtools-shell/e2e-regression.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<!doctype html>
<html>
<head>
<meta charset="utf8">
<title>React DevTools</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
* {
box-sizing: border-box;
}
body {
margin: 0;
padding: 0;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial,
sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;
font-size: 12px;
line-height: 1.5;
}
#iframe {
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 50vh;
}
#devtools {
position: absolute;
bottom: 0;
left: 0;
width: 100vw;
height: 50vh;
}
</style>
</head>
<body>
<iframe id="iframe"></iframe>
<div id="devtools"></div>
<script src="dist/e2e-devtools-regression.js"></script>
</body>
</html>
1 change: 1 addition & 0 deletions packages/react-devtools-shell/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
<a href="/multi.html">multi DevTools</a>
|
<a href="/e2e.html">e2e tests</a>
<a href="/e2e-regression.html">e2e regression tests</a>
</span>
</div>

Expand Down
3 changes: 2 additions & 1 deletion packages/react-devtools-shell/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
},
"dependencies": {
"immutable": "^4.0.0-rc.12",
"react-native-web": "0.0.0-26873b469"
"react-native-web": "0.0.0-26873b469",
"semver": "^6.3.0"
},
"devDependencies": {
"@babel/core": "^7.11.1",
Expand Down
55 changes: 55 additions & 0 deletions packages/react-devtools-shell/src/e2e-apps/ListAppLegacy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

import * as React from 'react';

export default function App() {
return <List />;
}

class List extends React.Component {
constructor(props) {
super(props);
this.state = {
items: ['one', 'two', 'three'],
};
}

addItem = () => {
if (this.inputRef && this.inputRef.value) {
this.setState({items: [...this.state.items, this.inputRef.value]});
this.inputRef.value = '';
}
};

render() {
return (
<div>
<input
data-testname="AddItemInput"
value={this.state.text}
onChange={this.onInputChange}
ref={c => (this.inputRef = c)}
/>
<button data-testname="AddItemButton" onClick={this.addItem}>
Add Item
</button>
<ul data-testname="List">
{this.state.items.map((label, index) => (
<ListItem key={index} label={label} />
))}
</ul>
</div>
);
}
}

function ListItem({label}) {
return <li data-testname="ListItem">{label}</li>;
}
33 changes: 33 additions & 0 deletions packages/react-devtools-shell/src/e2e-regression/app-legacy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/** @flow */

// This test harness mounts each test app as a separate root to test multi-root applications.

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import {gte} from 'semver';
import ListApp from '../e2e-apps/ListApp';
import ListAppLegacy from '../e2e-apps/ListAppLegacy';
const version = process.env.E2E_APP_REACT_VERSION;

function mountApp(App) {
const container = document.createElement('div');

((document.body: any): HTMLBodyElement).appendChild(container);

ReactDOM.render(<App />, container);
}
function mountTestApp() {
// ListApp has hooks, which aren't available until 16.8.0
mountApp(gte(version, '16.8.0') ? ListApp : ListAppLegacy);
}

mountTestApp();

// ReactDOM Test Selector APIs used by Playwright e2e tests
// If they don't exist, we mock them
window.parent.REACT_DOM_APP = {
createTestNameSelector: name => `[data-testname="${name}"]`,
findAllNodes: (container, nodes) =>
container.querySelectorAll(nodes.join(' ')),
...ReactDOM,
};
25 changes: 25 additions & 0 deletions packages/react-devtools-shell/src/e2e-regression/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/** @flow */

// This test harness mounts each test app as a separate root to test multi-root applications.

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import {createRoot} from 'react-dom/client';
import ListApp from '../e2e-apps/ListApp';

function mountApp(App) {
const container = document.createElement('div');

((document.body: any): HTMLBodyElement).appendChild(container);

const root = createRoot(container);
root.render(<App />);
}
function mountTestApp() {
mountApp(ListApp);
}

mountTestApp();

// ReactDOM Test Selector APIs used by Playwright e2e tests
window.parent.REACT_DOM_APP = ReactDOM;
54 changes: 54 additions & 0 deletions packages/react-devtools-shell/src/e2e-regression/devtools.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import {createRoot} from 'react-dom/client';
import {
activate as activateBackend,
initialize as initializeBackend,
} from 'react-devtools-inline/backend';
import {initialize as createDevTools} from 'react-devtools-inline/frontend';

// This is a pretty gross hack to make the runtime loaded named-hooks-code work.
// TODO (Webpack 5) Hoepfully we can remove this once we upgrade to Webpack 5.
// $FlowFixMer
__webpack_public_path__ = '/dist/'; // eslint-disable-line no-undef

// TODO (Webpack 5) Hopefully we can remove this prop after the Webpack 5 migration.
function hookNamesModuleLoaderFunction() {
return import('react-devtools-inline/hookNames');
}

function inject(contentDocument, sourcePath, callback) {
const script = contentDocument.createElement('script');
script.onload = callback;
script.src = sourcePath;

((contentDocument.body: any): HTMLBodyElement).appendChild(script);
}

function init(appIframe, devtoolsContainer, appSource) {
const {contentDocument, contentWindow} = appIframe;

initializeBackend(contentWindow);

const DevTools = createDevTools(contentWindow);

inject(contentDocument, appSource, () => {
// $FlowFixMe Flow doesn't know about createRoot() yet.
createRoot(devtoolsContainer).render(
<DevTools
hookNamesModuleLoaderFunction={hookNamesModuleLoaderFunction}
showTabBar={true}
/>,
);
});

activateBackend(contentWindow);
}

const iframe = document.getElementById('iframe');
const devtoolsContainer = document.getElementById('devtools');

init(iframe, devtoolsContainer, 'dist/e2e-app-regression.js');

// ReactDOM Test Selector APIs used by Playwright e2e tests
window.parent.REACT_DOM_DEVTOOLS = ReactDOM;
2 changes: 1 addition & 1 deletion packages/react-devtools-shell/src/e2e/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const container = document.createElement('div');

// TODO We may want to parameterize this app
// so that it can load things other than just ToDoList.
const App = require('./apps/ListApp').default;
const App = require('../e2e-apps/ListApp').default;

const root = createRoot(container);
root.render(<App />);
Expand Down
Loading