diff --git a/packages/react-devtools-inline/__tests__/__e2e__/inspecting-props.test.js b/packages/react-devtools-inline/__tests__/__e2e__/inspecting-props.test.js
index 9fbbce0f47df..5b6390c8a93f 100644
--- a/packages/react-devtools-inline/__tests__/__e2e__/inspecting-props.test.js
+++ b/packages/react-devtools-inline/__tests__/__e2e__/inspecting-props.test.js
@@ -8,9 +8,11 @@ test.describe('Testing Todo-List App', () => {
let page, frameElementHandle, frame;
test.beforeAll(async ({browser}) => {
page = await browser.newPage();
- await page.goto('http://localhost:8080/', {waitUntil: 'domcontentloaded'});
- await page.waitForSelector('iframe#target');
- frameElementHandle = await page.$('#target');
+ await page.goto('http://localhost:8080/e2e.html', {
+ waitUntil: 'domcontentloaded',
+ });
+ await page.waitForSelector('iframe#iframe');
+ frameElementHandle = await page.$('#iframe');
frame = await frameElementHandle.contentFrame();
});
@@ -42,7 +44,7 @@ test.describe('Testing Todo-List App', () => {
for (let i = 1; i <= countOfItems; ++i) {
await page.click('[class^=ToggleContent]', {delay: 100});
await frame.click(`.listitem:nth-child(${i})`, {delay: 50});
- await page.waitForSelector('span.Value___tNzum');
+ await page.waitForSelector('span[class^=Value]');
const text = await page.innerText('span[class^=Value]');
await expect(text).toEqual(listItemsProps[i]);
}
diff --git a/packages/react-devtools-shell/e2e.html b/packages/react-devtools-shell/e2e.html
new file mode 100644
index 000000000000..93d8f2f3f81d
--- /dev/null
+++ b/packages/react-devtools-shell/e2e.html
@@ -0,0 +1,40 @@
+
+
+
+
+ React DevTools
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packages/react-devtools-shell/app.html b/packages/react-devtools-shell/index.html
similarity index 90%
rename from packages/react-devtools-shell/app.html
rename to packages/react-devtools-shell/index.html
index 7bd183891a99..bc539559bbb6 100644
--- a/packages/react-devtools-shell/app.html
+++ b/packages/react-devtools-shell/index.html
@@ -48,8 +48,9 @@
- Chrome extension
- Firefox extension
+ multi DevTools
+ |
+ e2e tests
diff --git a/packages/react-devtools-shell/package.json b/packages/react-devtools-shell/package.json
index 776085ec0618..15eecd46325c 100644
--- a/packages/react-devtools-shell/package.json
+++ b/packages/react-devtools-shell/package.json
@@ -3,9 +3,7 @@
"name": "react-devtools-shell",
"version": "0.0.0",
"scripts": {
- "start": "yarn start:app",
- "start:app": "cross-env NODE_ENV=development cross-env TARGET=local webpack-dev-server --open-page app.html",
- "start:multi": "cross-env NODE_ENV=development cross-env TARGET=local webpack-dev-server --open-page multi.html"
+ "start": "cross-env NODE_ENV=development cross-env TARGET=local webpack-dev-server"
},
"dependencies": {
"immutable": "^4.0.0-rc.12",
diff --git a/packages/react-devtools-shell/src/e2e/app.js b/packages/react-devtools-shell/src/e2e/app.js
new file mode 100644
index 000000000000..97ede9b56635
--- /dev/null
+++ b/packages/react-devtools-shell/src/e2e/app.js
@@ -0,0 +1,20 @@
+/** @flow */
+
+// This test harness mounts each test app as a separate root to test multi-root applications.
+
+import {createElement} from 'react';
+import {
+ // $FlowFixMe Flow does not yet know about createRoot()
+ createRoot,
+} from 'react-dom';
+import ToDoList from '../app/ToDoList';
+
+const container = document.createElement('div');
+
+((document.body: any): HTMLBodyElement).appendChild(container);
+
+// TODO We may want to parameterize this app
+// so that it can load things other than just ToDoList.
+
+const root = createRoot(container);
+root.render(createElement(ToDoList));
diff --git a/packages/react-devtools-shell/src/e2e/devtools.js b/packages/react-devtools-shell/src/e2e/devtools.js
new file mode 100644
index 000000000000..68717ca1e921
--- /dev/null
+++ b/packages/react-devtools-shell/src/e2e/devtools.js
@@ -0,0 +1,34 @@
+import * as React from 'react';
+import {createRoot} from 'react-dom';
+import {
+ activate as activateBackend,
+ initialize as initializeBackend,
+} from 'react-devtools-inline/backend';
+import {initialize as createDevTools} from 'react-devtools-inline/frontend';
+
+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, () => {
+ createRoot(devtoolsContainer).render();
+ });
+
+ activateBackend(contentWindow);
+}
+
+const iframe = document.getElementById('iframe');
+const devtoolsContainer = document.getElementById('devtools');
+
+init(iframe, devtoolsContainer, 'dist/e2e-app.js');
diff --git a/packages/react-devtools-shell/webpack.config.js b/packages/react-devtools-shell/webpack.config.js
index 4f690bb0e3c2..496bdabd6b76 100644
--- a/packages/react-devtools-shell/webpack.config.js
+++ b/packages/react-devtools-shell/webpack.config.js
@@ -44,6 +44,8 @@ const config = {
entry: {
'app-index': './src/app/index.js',
'app-devtools': './src/app/devtools.js',
+ 'e2e-app': './src/e2e/app.js',
+ 'e2e-devtools': './src/e2e/devtools.js',
'multi-left': './src/multi/left.js',
'multi-devtools': './src/multi/devtools.js',
'multi-right': './src/multi/right.js',