New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
edges not rendered to JSDOM when testing with Jest and React Testing Library #716
Comments
Hey @kislakiruben I could imagine that react flow is not finished with rendering. It seems that it only rendered the first tick. Maybe you could use |
yes, I tried to do that, but I got the same result. I'm wondering whether it has anything to do with how easy-peasy is initializing the state. |
I have the same issue. I'll try to create a sandbox for this |
This works for me locally but I'm not able to make it work in the sandbox. I may be missing something. Here is the link if anyone wants to give it a try https://codesandbox.io/s/blissful-spence-hnozn |
Could you solve this @kislakiruben ? |
Not really. I ditched writing unit tests for the graph implementaion. |
All I needed to do is to mock the ResizeObserver to get this running. I used a fresh CRA and the latest version (8.4.1) of react flow. |
@moklick can you show how you mocked the ResizeObserver? |
in import { ResizeObserver } from '@juggle/resize-observer';
global.ResizeObserver = ResizeObserver; |
Could you check if it works for you with the current version @kislakiruben ? |
@moklick it looks like it works with the latest version ( |
I'm not sure, but I believe this commit fixed it: d6a410a |
Ok, cool! Feel free to re-open this issue if you encounter a problem with react-flow + testing-library/react. |
I just checked this with 8.7.0 and it is working. |
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:
But still no nodes and edges are rendered. Notes:
@MatiasCiccone @kislakiruben can you confirm you are able to access the elements within react flow in your tests? |
i am having a similar issue. when running tests, nodes are being rendered, but edges are not. i am using version |
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 This width is set by getting 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: jsdom/jsdom#135, and can pretty much be solved by putting this in your code: Object.defineProperties(window.HTMLElement.prototype, {
offsetHeight: {
get() { return parseFloat(this.style.height) || 1; },
},
offsetWidth: {
get() { return parseFloat(this.style.width) || 1; },
},
}); 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. |
where would you put this code in? When I put it into |
I put it in the test file itself (eg: MyComponent.test.tsx) inside
@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. |
@gfox1984 Thanks for providing the test file. It added coverage onto the CustomEdge component when I render the React Flow diagram. As for my specific warning/error that I am seeing, I changed the |
@gfox1984, @Zachary Heller: I could still see this issue in the latest version, edges are not rendering in test. Do you have any solution? |
Sadly I am also experiencing the same issue where edges are not visible in tests after applying #716 (comment). It does seem that the edges are been calculated but never rendered: <svg
class="react-flow__edges react-flow__container"
height="1"
style="z-index: 0;"
width="1"
>
<defs />
<g /> <----
</svg> using |
Hey everyone, I looked into this but I haven't found a good solution yet. There are two problems:
Can anyone help here? |
Thanks @bcakmakoglu ! I have an idea.. I will just do something like this: export function getScaleFromElement(element: HTMLDivElement): number {
if (window.DOMMatrixReadOnly) {
const style = window.getComputedStyle(element);
const { m22 } = new window.DOMMatrixReadOnly(style.transform);
return m22;
}
const scale = element.style?.transform?.match(/scale\(([1-9.])\)/)?.[1];
return scale !== undefined ? +scale : 1;
} |
Hey, sorry, I'm late to the party. I haven't updated reactflow in a while, so yes it's possible that there's more that needs to be mocked now. I guess that window.DOMMatrixReadOnly needs a polyfill. I haven't tried it, but I see that there is one available here: https://github.com/thednp/dommatrix. Then you should be able to do something like this:
@moklick I'm not sure it's a good idea to start adding fallbacks to the code just for Jest, although I agree that it would be convenient and that it's not really specific to Jest either (you could see it as a general fallback for exotic browsers). But maybe a better approach would be to create an interface for all the DOM-specific operations that are not available in the testing environment, then add an optional prop to the ReactFlow Provider to be able pass an implementation for it (= dependency injection). If not provided, you'd use your default implementation based on the actual DOMMatrixReadOnly, ResizeObserver, etc. In Jest, we'd just use our own (or you could also provide a package (or export some utilities) to help with that.) |
@gfox1984 I agree! Would be better to mock things from within |
You should be able to do this:
|
Good news. I've found a better solution. You can get rid of the Updated // To make sure that the tests are working, it's important that you are using
// this implementation of ResizeObserver and DOMMatrixReadOnly
class ResizeObserver {
callback: globalThis.ResizeObserverCallback;
constructor(callback: globalThis.ResizeObserverCallback) {
this.callback = callback;
}
observe(target: Element) {
this.callback([{ target } as globalThis.ResizeObserverEntry], this);
}
unobserve() {}
disconnect() {}
}
global.ResizeObserver = ResizeObserver;
class DOMMatrixReadOnly {
m22: number;
constructor(transform: string) {
const scale = transform?.match(/scale\(([1-9.])\)/)?.[1];
this.m22 = scale !== undefined ? +scale : 1;
}
}
// @ts-ignore
global.DOMMatrixReadOnly = DOMMatrixReadOnly;
Object.defineProperties(global.HTMLElement.prototype, {
offsetHeight: {
get() {
return parseFloat(this.style.height) || 1;
},
},
offsetWidth: {
get() {
return parseFloat(this.style.width) || 1;
},
},
});
(global.SVGElement as any).prototype.getBBox = () => ({
x: 0,
y: 0,
width: 0,
height: 0,
});
export {}; I'll updated the docs, too: https://reactflow.dev/docs/guides/testing/ |
Nice ! Thank you @moklick, I applied the changes above and both nodes and edges are now fully visible in my jest tests 👍 |
@Bars92 Are you able to use |
I'm using storybook and creating storyshot for jest to test using addon-storyshots global.DOMMatrixReadOnly = DOMMatrixReadOnly; and RAN "yarn jest --collect-coverage"
Error: TypeError: P.current.closest is not a function It seems like its breaking here: Line 105: domNode: zoomPane.current.closest('.react-flow') as HTMLDivElement My Storyshot
|
@moklick did you got chance to look at the issue ? |
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:
And then I try to test it:
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.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:The text was updated successfully, but these errors were encountered: