enzyme-adapter-react-17
enzyme-adapter-react-17 copied to clipboard
displayName no longer appears on many React Native components
Hi, I've switched over to this library as part of our React 17 upgrade. We are using React Native.
I've noticed that all our snapshots (several thousand) in the project failed due to the displayName
of many components changing to a generic Component
.
I think this is to do with the Object.assign
forcing the display name to be Component
in the methods wrapPureComponent
and wrapFunctionalComponent
.
https://github.com/wojtekmaj/enzyme-adapter-react-17/blob/d33c2925e402c39928dfabf2ecfd41063fb2f3a8/src/ReactSeventeenAdapter.js#L562
Is this right and can anything be done about it?
![Screenshot 2021-12-09 at 20 21 10](https://user-images.githubusercontent.com/2470659/145469883-f629d1d2-8188-49db-abdc-1f4febc28690.png)
p.s. I think it's great that you have released this despite the Enzyme maintainers refusing to release their React 17 adapter!
After using the debugger and stepping through the library I located the source of the issue.
React Native attaches its displayName
to ForwardRef in this way:
https://github.com/facebook/react-native/blob/main/Libraries/Components/View/View.js#L37
However in the context of the React adapter it doesn't find it because it is looking for node.type.displayName
. The RN name is in fact under node.type.render.displayName
.
![Screenshot 2021-12-09 at 21 15 52](https://user-images.githubusercontent.com/2470659/145477632-618d1378-a124-46c3-acf9-65f44bb042d2.png)
In fact, adapter.displayNameOfNode
would return this correctly, but for some reason RN components have both type.displayName = 'Component' and
type.render.displayName = 'View'`. So the method returns before the more advanced name find can occur.
https://github.com/wojtekmaj/enzyme-adapter-react-17/blob/main/src/ReactSeventeenAdapter.js#L865
case require("react-is").ForwardRef || NaN:
{
// vvv this check is stopping adapter.displayNameOfNode from running and all `ForwardRef` returns 'Component' as name.
if (type.displayName) {
return type.displayName;
}
// since this has `type.render` passed to it, it will return the correct displayName.
var name = adapter.displayNameOfNode({
type: type.render });
return name ? "ForwardRef(".concat(name, ")") : 'ForwardRef';
}
This could be fixed by possibly switching the order of invocation. I fixed it with a crude patch below which is suitable for our use...
diff --git a/node_modules/@wojtekmaj/enzyme-adapter-react-17/build/ReactSeventeenAdapter.js b/node_modules/@wojtekmaj/enzyme-adapter-react-17/build/ReactSeventeenAdapter.js
index e4a1837..aaf1700 100644
--- a/node_modules/@wojtekmaj/enzyme-adapter-react-17/build/ReactSeventeenAdapter.js
+++ b/node_modules/@wojtekmaj/enzyme-adapter-react-17/build/ReactSeventeenAdapter.js
@@ -1041,6 +1041,10 @@ var ReactSeventeenAdapter = /*#__PURE__*/function (_EnzymeAdapter) {
case _reactIs.ForwardRef || NaN:
{
+ if (type.render && type.render.displayName) {
+ return type.render.displayName;
+ }
+
if (type.displayName) {
return type.displayName;
}
@nabilfreeman Unfortunately this workaround breaks a few tests we have, so I can't add this.