Skip to content
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

Error clicking node in React Flow in jest test with @testing-library #2587

Closed
quantti opened this issue Nov 23, 2022 · 13 comments
Closed

Error clicking node in React Flow in jest test with @testing-library #2587

quantti opened this issue Nov 23, 2022 · 13 comments

Comments

@quantti
Copy link

quantti commented Nov 23, 2022

Describe the Bug

We have test runned with jest and react-testing-library. When test is run, everything works fine until node or any element inside node is clicked:

TypeError: Cannot read properties of null (reading 'document')

      at Ke (node_modules/reactflow/dist/umd/index.js:10:15269)
      at HTMLDivElement.E (node_modules/reactflow/dist/umd/index.js:10:74213)
      at HTMLDivElement.<anonymous> (node_modules/reactflow/dist/umd/index.js:10:7374)
      at HTMLDivElement.callTheUserObjectsOperation (node_modules/jsdom/lib/jsdom/living/generated/EventListener.js:26:30)
      at innerInvokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:338:25)
      at invokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:274:3)
      at HTMLDivElementImpl._dispatch (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:221:9)
      at HTMLDivElementImpl.dispatchEvent (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:94:17)
      at HTMLDivElement.dispatchEvent (node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:231:34)
      at node_modules/@testing-library/user-event/dist/cjs/event/dispatchEvent.js:47:43
      at node_modules/@testing-library/react/dist/pure.js:64:16
      at batchedUpdates$1 (node_modules/react-dom/cjs/react-dom.development.js:22380:12)
      at act (node_modules/react-dom/cjs/react-dom-test-utils.development.js:1042:14)
      at Object.eventWrapper (node_modules/@testing-library/react/dist/pure.js:63:28)
      at Object.wrapEvent (node_modules/@testing-library/user-event/dist/cjs/event/wrapEvent.js:8:28)
      at Object.dispatchEvent (node_modules/@testing-library/user-event/dist/cjs/event/dispatchEvent.js:47:22)
      at Object.dispatchUIEvent (node_modules/@testing-library/user-event/dist/cjs/event/dispatchEvent.js:24:26)
      at Mouse.down (node_modules/@testing-library/user-event/dist/cjs/system/pointer/mouse.js:70:34)
      at PointerHost.press (node_modules/@testing-library/user-event/dist/cjs/system/pointer/index.js:27:24)
      at pointerAction (node_modules/@testing-library/user-event/dist/cjs/pointer/index.js:59:43)
      at Object.pointer (node_modules/@testing-library/user-event/dist/cjs/pointer/index.js:35:15)
      at node_modules/@testing-library/react/dist/pure.js:57:16

I have tried to add nodesDraggable={false} to ReactFlow and className='nodrag' to Node, but that doesn't help. We have added needed lines described in documentation to testUtils.ts. Nodes and elements inside nodes are rendered and pass test.

Your Example Website or App

No response

Steps to Reproduce the Bug or Issue

Unfortunately can't share any actual code, other than test case:

const user = userEvent.setup();
const { getAllByText, getByTestId, getByText } = render(<WrappedReactFlow />);
await waitForElementToBeRemoved(getByTestId('loading-spinner'));
expect(getAllByText(/node title/i).length).toBe(1);
const node = getByText(/node title/i);
await user.click(node);

That's pretty much is failing test case. Last line produces the error.

Wrapper includes mocks to redux store, API calls, history and GraphQL (moving to GQL, but still using some legacy for a while) and everything with those seem to work, as nodes are rendered.

Expected behavior

As a user I expect Node to be selected with no error and I can further test my app.

Screenshots or Videos

No response

Platform

  • OS: macOS, Linux
  • Browser: no browser
  • Version: 11.1.1
  • React 17
  • Jest 27.4.4
  • @testing-library/react 11.2.5
  • @testing-libaray/user-event 14.4.3

Additional context

No response

@moklick
Copy link
Member

moklick commented Nov 23, 2022

hey! Did you see this issue #2461 (comment) ? Does it solve your problem?

@quantti
Copy link
Author

quantti commented Nov 23, 2022

I did, but now I did again and it worked, because I removed nodesDraggable={false} from ReactFlow. Thanks!

@moklick
Copy link
Member

moklick commented Nov 23, 2022

I am glad it worked out!

@moklick moklick closed this as completed Nov 23, 2022
@quantti
Copy link
Author

quantti commented Nov 23, 2022

It's not very optimal thought for testing purposes, as I cannot select node at the moment either. But at least I can make some of the tests work now, it's a start.

@moklick
Copy link
Member

moklick commented Nov 23, 2022

Why can't you select a node?

@quantti
Copy link
Author

quantti commented Nov 24, 2022

I can select node, but not with just mouse click. Could be something with how my custom node is built, as it is selectable by space after clicking it and it can be selected by tab. Anyway was able to get around it. Thanks again!

@penx
Copy link

penx commented Jan 27, 2023

Why can't you select a node?

I'd like to be able to write a test that clicks on a node to select:

  await waitFor(() =>
    userEvent.click(canvas.getByRole(/* code to click on a specific node */)),
  );

But this errors with "Cannot read properties of null (reading 'document')".

Disabling dragging works, but I don't want to disable it, as it's a feature we're using.

I understand this is an upstream issue, but would be good to track it.

@penx
Copy link

penx commented Jan 27, 2023

I will open a new issue against d3-drag, as the previous one was closed without a fix

@penx
Copy link

penx commented Jan 27, 2023

@penx
Copy link

penx commented Jan 27, 2023

In the meantime, I think this can be resolved by either:

    userEvent.click(canvas.getByRole(/* */), {
      view: window,
    }),

or mocking window if running in a non browser environment, maybe something like:

    userEvent.click(canvas.getByRole(/* */), {
      view: new JSDOM().window,
    }),

@radegran
Copy link

Thanks for a great library!
This issue is still a problem for me though.

@penx Did you manage to find a better solution?

My setup:

  • In my app I show a symbol for unsaved changes in the "document" - pretty much a reactflow instance.
  • For example, when a user repositions a node by dragging, this symbol should lit up.
  • Node selection is not part of the document's state, no need to show the unsaved-changes symbol then.

My bug:

  • When the user clicks on a node it gets selected, and the unsaved-changes symbol shows.

The issue:

  • When the user clicks on a node a drag operation is started and stopped, causing my handler provided to ReactFlow's onNodeDragStop callback. A fix would probably involve checking if the state (manage by me) has actually changed. Currently my code just make the state update (nothing has changed) and assumes the unsaved-changes symbol should lit up.

This is my problem
I would like to write a test where the user clicks on a node and assert that the unsaved-changes symbol has not been lit. Disabling dragging is not an option because that's where the bug is. @moklick, do you have any ideas?

Thanks!

@penx
Copy link

penx commented Feb 23, 2024

I don't have access to the code where I had this issue anymore, but pretty sure my last comment above was working for us

@radegran
Copy link

Thanks @penx, user-event v14 API has changed the API and I haven't figured out to achieve the same thing there... :/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants