xyflow: edges not rendered to JSDOM when testing with Jest and React Testing Library
Hi!
I’m having some issue on making the nodes and edges to show up when I’m rendering the graph to JSDOM with Jest and React Testing Library. I have the following set up:
//App.js
import ReactFlow from "react-flow-renderer";
const App = () => (
<ReactFlow
elements={[
{
data: { label: "a" },
id: "b",
position: { x: 10, y: 10 },
},
{
data: { label: "b" },
id: "a",
position: { x: 10, y: 80 },
},
{
id: "edge-a-b",
source: "a",
target: "b",
},
]}
/>
);
And then I try to test it:
//App.test.js
import { render } from "@testing-library/react";
import App from "./App";
it("should render", async () => {
const { debug, getByText } = render(<App />);
debug();
expect(getByText("a")).toBeInTheDocument();
});
The test fails because the node is not rendered. If I do a debug
, I can see that the wrapper elements for the graph are being rendered, but no nodes or edges.
<body>
<div>
<div
class="react-flow"
>
<div
class="react-flow__renderer react-flow__zoompane"
>
<div
class="react-flow__nodes"
style="transform: translate(0px,0px) scale(1);"
/>
<svg
class="react-flow__edges"
height="500"
width="500"
>
<defs>
<marker
class="react-flow__arrowhead"
id="react-flow__arrowclosed"
markerHeight="12.5"
markerWidth="12.5"
orient="auto"
refX="0"
refY="0"
viewBox="-10 -10 20 20"
>
<polyline
fill="#b1b1b7"
points="-5,-4 0,0 -5,4 -5,-4"
stroke="#b1b1b7"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="1"
/>
</marker>
<marker
class="react-flow__arrowhead"
id="react-flow__arrow"
markerHeight="12.5"
markerWidth="12.5"
orient="auto"
refX="0"
refY="0"
viewBox="-10 -10 20 20"
>
<polyline
fill="none"
points="-5,-4 0,0 -5,4"
stroke="#b1b1b7"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="1.5"
/>
</marker>
</defs>
<g
transform="translate(0,0) scale(1)"
/>
</svg>
<div
class="react-flow__pane"
/>
</div>
</div>
</div>
</body>
I wanted to set up a codesandbox, but I couldn’t get to polyfill ResizeObserver
.
Any ideas on what might be going on and how to ‘fix’ it?
EDIT: if I pass a callback to onLoad
, I can see the elements in there:
import ReactFlow from "react-flow-renderer";
const App = () => {
const onLoad = (instance) => {
console.log(instance.getElements());
};
return (<ReactFlow elements={[...]} onLoad={onLoad} />);
};
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 3
- Comments: 33 (11 by maintainers)
I put it in the test file itself (eg: MyComponent.test.tsx) inside
beforeAll
. Below is my setup:@moklick I think it would be useful to add an example to the site. Most people use Jest + Testing Library in their application, and setting up tests is a bit challenging.
Hey everyone,
I looked into this but I haven’t found a good solution yet. There are two problems:
"[TypeError: window.DOMMatrixReadOnly is not a constructor"
I don’t understand why this is not supported by jest or why I can’t find anything about it. It’s a dom library that is supoorted by all browsers https://developer.mozilla.org/en-US/docs/Web/API/DOMMatrixReadOnlyCan anyone help here?
Nice ! Thank you @moklick, I applied the changes above and both nodes and edges are now fully visible in my jest tests 👍
Hey there,
Ran into this bug. I’m pretty sure I found the root problem in react-testing library. First, like folks have noted you need to make sure to mock the RenderObserver for things to really just work to begin with. After that, nodes will render but edges don’t. Edges aren’t being rendered because in edge initialization it bails out if the source node
__rf.width
isn’t set: https://github.com/wbkd/react-flow/blob/main/src/container/EdgeRenderer/index.tsx#L90This width is set by getting
node.offsetWidth
here: https://github.com/wbkd/react-flow/blob/41db69e06c22d278657ba810198f371119b4972b/src/utils/index.ts#L14.React-testing-library uses jsdom under the hood, which by design doesn’t implement layout, but this is effectively the same problem people are discussing here: https://github.com/jsdom/jsdom/issues/135, and can pretty much be solved by putting this in your code:
To stub out the methods to ensure node width isn’t falsy, and then you get edges rendered.
I’m not really sure if there is much that needs to be fixed in this library, since I don’t think it makes sense for it to be aware of the fact that it’t not actually being rendered… but I think it might be solved by an example.
Hey, sorry I’m a bit confused here. What exactly is working? I’m running version 9.3.2 (the latest), and I still have the original problem that no edges or nodes are rendered in the tests.
I tried adding:
which fixes this error:
console.error Error: Uncaught [ReferenceError: ResizeObserver is not defined]
But still no nodes and edges are rendered.
Notes:
console.warn The React Flow parent container needs a width and a height to render the graph.
, despite wrapping ReactFlow into<div style={{ width: 500, height: 500 }}>
onlyRenderVisibleElements={false}
, but it did not make a difference@MatiasCiccone @kislakiruben can you confirm you are able to access the elements within react flow in your tests?
Good news. I’ve found a better solution. You can get rid of the
@juggle/resize-observer
dependency and don’t need to pass a fake width and height to your nodes in order to test them. The trick is to create a ResizeObserver class that works slighty different than the original one.Updated
setupTests.ts
:I’ll updated the docs, too: https://reactflow.dev/docs/guides/testing/
Thanks @bcakmakoglu ! I have an idea… I will just do something like this:
@gfox1984, @Zachary Heller: I could still see this issue in the latest version, edges are not rendering in test. Do you have any solution?
in
setupTests.js
: