mirror of
https://github.com/microsoft/playwright.git
synced 2024-11-28 01:15:10 +03:00
parent
3b2d247c74
commit
cbf4f39957
@ -147,16 +147,20 @@ function findReactRoots(root: Document | ShadowRoot, roots: ReactVNode[] = []):
|
||||
do {
|
||||
const node = walker.currentNode;
|
||||
|
||||
const reactNode = node as { readonly [customKey: string]: any };
|
||||
// React 17+
|
||||
// React sets rootKey when mounting
|
||||
// @see https://github.com/facebook/react/blob/a724a3b578dce77d427bef313102a4d0e978d9b4/packages/react-dom/src/client/ReactDOMComponentTree.js#L62-L64
|
||||
const rootKey = Object.keys(node).find(key => key.startsWith('__reactContainer'));
|
||||
const rootKey = Object.keys(reactNode).find(key => key.startsWith('__reactContainer') && reactNode[key] !== null);
|
||||
if (rootKey) {
|
||||
roots.push((node as any)[rootKey].stateNode.current);
|
||||
} else if (node.hasOwnProperty('_reactRootContainer')) {
|
||||
// ReactDOM Legacy client API:
|
||||
// @see https://github.com/baruchvlz/resq/blob/5c15a5e04d3f7174087248f5a158c3d6dcc1ec72/src/utils.js#L329
|
||||
roots.push((node as any)._reactRootContainer._internalRoot.current);
|
||||
roots.push(reactNode[rootKey].stateNode.current);
|
||||
} else {
|
||||
const legacyRootKey = '_reactRootContainer';
|
||||
if (reactNode.hasOwnProperty(legacyRootKey) && reactNode[legacyRootKey] !== null) {
|
||||
// ReactDOM Legacy client API:
|
||||
// @see https://github.com/baruchvlz/resq/blob/5c15a5e04d3f7174087248f5a158c3d6dcc1ec72/src/utils.js#L329
|
||||
roots.push(reactNode[legacyRootKey]._internalRoot.current);
|
||||
}
|
||||
}
|
||||
|
||||
// Pre-react 16: rely on `data-reactroot`
|
||||
|
@ -102,8 +102,12 @@ class App extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
window.mountApp = element => ReactDOM.render(e(App, null, null), element);
|
||||
window.mountApp = element => {
|
||||
const root = ReactDOM.render(e(App, null, null), element);
|
||||
const unmount = () => ReactDOM.unmountComponentAtNode(element);
|
||||
return {root, unmount};
|
||||
};
|
||||
window.app = window.mountApp(document.getElementById('root'));
|
||||
window.mountNestedApp = () => window.mountApp(window.app.refs.mountPoint);
|
||||
window.mountNestedApp = () => window.mountApp(window.app.root.refs.mountPoint);
|
||||
|
||||
</script>
|
||||
|
@ -50,7 +50,7 @@ class NewBook extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
return e(React.Fragment, null,
|
||||
return e(React.Fragment, null,
|
||||
e('input', {onInput: this.onInput.bind(this)}, null),
|
||||
e('button', {
|
||||
onClick: () => this.props.onNewBook(this.state),
|
||||
@ -101,9 +101,13 @@ class App extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
window.mountApp = element => ReactDOM.render(e(App, null, null), element);
|
||||
window.mountApp = element => {
|
||||
const root = ReactDOM.render(e(App, null, null), element);
|
||||
const unmount = () => ReactDOM.unmountComponentAtNode(element);
|
||||
return {root, unmount};
|
||||
};
|
||||
window.app = window.mountApp(document.getElementById('root'));
|
||||
|
||||
window.mountNestedApp = () => window.mountApp(window.app.mountPoint.current);
|
||||
window.mountNestedApp = () => window.mountApp(window.app.root.mountPoint.current);
|
||||
|
||||
</script>
|
||||
|
@ -95,8 +95,12 @@ class App extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
window.mountApp = element => ReactDOM.render(e(App, null, null), element);
|
||||
window.mountApp = element => {
|
||||
const root = ReactDOM.render(e(App, null, null), element);
|
||||
const unmount = () => ReactDOM.unmountComponentAtNode(element);
|
||||
return {root, unmount};
|
||||
};
|
||||
window.app = window.mountApp(document.getElementById('root'));
|
||||
window.mountNestedApp = () => window.mountApp(window.app.mountPoint.current);
|
||||
window.mountNestedApp = () => window.mountApp(window.app.root.mountPoint.current);
|
||||
|
||||
</script>
|
||||
|
@ -156,6 +156,19 @@ for (const [name, url] of Object.entries(reacts)) {
|
||||
});
|
||||
await expect(page.locator(`_react=BookItem`)).toHaveCount(6);
|
||||
});
|
||||
|
||||
it('should work with multiroot react after unmount', async ({ page }) => {
|
||||
await expect(page.locator(`_react=BookItem`)).toHaveCount(3);
|
||||
|
||||
await page.evaluate(() => {
|
||||
const anotherRoot = document.createElement('div');
|
||||
document.body.append(anotherRoot);
|
||||
// @ts-ignore
|
||||
const newRoot = window.mountApp(anotherRoot);
|
||||
newRoot.unmount();
|
||||
});
|
||||
await expect(page.locator(`_react=BookItem`)).toHaveCount(3);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user