-
-
Notifications
You must be signed in to change notification settings - Fork 2k
Open
Description
Current behavior
Getting error Enzyme Internal Error: unknown node with tag 2
from mounting Suspense component with child component that throws promise:
import React, { Suspense } from "react";
const Message = props => <div>Hello Enzyme!</div>
const Loading = props => <div>loading...</div>
const Thrower = props => {
throw new Promise(resolve => {
setTimeout(resolve, 1000);
});
};
describe("integration with Suspense component", () => {
test("should render Message component", () => {
const wrapper = mount(
<Suspense fallback={<Loading />}>
<Message />
</Suspense>
);
expect(wrapper.find(Message)).toExist(); // ✅ passes
});
test("should render Loading component", () => {
const wrapper = mount(
<Suspense fallback={<Loading />}>
<Thrower />
</Suspense>
);
expect(wrapper.find(Loading)).toExist(); // ❌ Enzyme Internal Error: unknown node with tag 2
});
})trace:
Enzyme Internal Error: unknown node with tag 2
20 |
21 | test("should render Loading component", () => {
> 22 | const wrapper = mount(
| ^
23 | <Suspense fallback={<Loading />}>
24 | <Thrower />
25 | </Suspense>
at _toTree (node_modules/enzyme-adapter-react-16/src/ReactSixteenAdapter.js:254:13)
at toTree (node_modules/enzyme-adapter-react-16/src/ReactSixteenAdapter.js:267:12)
at childrenToTree (node_modules/enzyme-adapter-react-16/src/ReactSixteenAdapter.js:227:14)
at Array.map (<anonymous>)
at map (node_modules/enzyme-adapter-react-16/src/ReactSixteenAdapter.js:269:27)
at childrenToTree (node_modules/enzyme-adapter-react-16/src/ReactSixteenAdapter.js:248:19)
at toTree (node_modules/enzyme-adapter-react-16/src/ReactSixteenAdapter.js:267:12)
at childrenToTree (node_modules/enzyme-adapter-react-16/src/ReactSixteenAdapter.js:169:19)
at Object.toTree [as getNode] (node_modules/enzyme-adapter-react-16/src/ReactSixteenAdapter.js:448:11)
at new getNode (node_modules/enzyme/src/ReactWrapper.js:117:44)
at mount (node_modules/enzyme/src/mount.js:10:10)
at Object.mount (__tests__/Suspense.spec.js:22:21)
Expected behavior
No error
Your environment
API
- shallowmountrenderTo pick up a draggable item, press the space bar. While dragging, use the arrow keys to move the item. Press space again to drop the item in its new position, or press escape to cancel.
Version
| library | version |
|---|---|
| enzyme | 3.10.0 |
| jest-enzyme | 7.0.2 |
| react | 16.8.6 |
| react-dom | 16.8.6 |
| react-test-renderer | 16.8.6 |
| adapter (below) | 1.14.0 |
Adapter
- enzyme-adapter-react-16enzyme-adapter-react-16.3enzyme-adapter-react-16.2enzyme-adapter-react-16.1enzyme-adapter-react-15enzyme-adapter-react-15.4enzyme-adapter-react-14enzyme-adapter-react-13enzyme-adapter-react-helperothers ( )To pick up a draggable item, press the space bar. While dragging, use the arrow keys to move the item. Press space again to drop the item in its new position, or press escape to cancel.
OlgaKuksa, amowu, Arnarkari93, dotexe0, tilwinjoy and 1 more
Metadata
Metadata
Assignees
Type
Projects
Milestone
Relationships
Development
Select code repository
Activity
json2d commentedon Jul 30, 2019
#1917 #1975
ljharb commentedon Jul 30, 2019
Looks related to #2125.
ljharb commentedon Jul 30, 2019
Does this only occur when you throw a promise, as opposed to another kind of exception?
json2d commentedon Jul 30, 2019
Yep,
throw new Error()instead of a promise doesn't yield this kind of messageljharb commentedon Jul 30, 2019
So you're not using any
React.lazycomponents - which have to be a promise for an object with adefaultproperty that's a React component - but I'm not sure you're supposed to be able to throw a promise directly inside Suspense.Can you link me to the React docs that talk about this? https://reactjs.org/docs/code-splitting.html doesn't seem to.
json2d commentedon Jul 30, 2019
Throwing a promise inside Suspense should be the way to implement an async component - afaik.
here's a pretty recent article that talks about it:
https://blog.logrocket.com/the-future-of-react-unfolding-with-suspense/
The part about
React.lazyyou're referencing from the React docs talks about theimportreturning a promise that resolves to a module with anexport defaultthat's a React component.ljharb commentedon Jul 30, 2019
hmm, in that case perhaps the "thrown promise" case isn't something we're handling properly.
CrOrc commentedon Jul 31, 2019
Throwing promise inside render is supported by React Suspense.
See pull request in React repo Accept promise as element type
OlgaKuksa commentedon Sep 2, 2019
Hi there, is there any update on the issue? Looking forward for it to be fixed!
jeffersoneagley commentedon Mar 19, 2020
Still broken?
nickpalmer commentedon Aug 26, 2020
react-lazy-ssr triggers this error because it throws a promise.
While there is a workaround, it would be nice if Enzyme supported it without the workaround.
rdy commentedon Sep 13, 2020
I also ran into this issue testing recoil with enzyme and using a value that returns a promise.
It would be nice to be able to use suspense with enzyme.
ljharb commentedon Sep 15, 2020
I'm working on fixing this, but the "detect fiber tags" code we use is having trouble figuring out the 17 (it has to be done dynamically so it doesn't break over time).
artola commentedon Jun 4, 2021
@ljharb I found this problem using v1.15.6 of the adapter. I am using
relay v11withrelay-test-utils. Do you have some hint?ljharb commentedon Jun 4, 2021
@artola i can reproduce the issue, but i can't figure out yet how to update our internals to handle it.
artola commentedon Jun 4, 2021
I will give it a try. Thanks.
artola commentedon Jun 4, 2021
@ljharb I did some changes and it seems to work for me (at least my test is working), but I have not your experience and broad vision. Does it makes some sense?
There is also a
ClassComponentLazythat should be supported.ljharb commentedon Jun 4, 2021
@artola if you can make a PR with passing tests, then that sounds awesome.
totszwai commentedon Jan 19, 2022
Failing without any async nor Promise.