How to paste clipboard data using React Testing Library?

Viewed 6337

I'm trying to paste text that's already in my clipboard into a textbox, but I dont understand how to use "eventInit" to do this. I've read the documentation on how to paste text into a textbox, but it isn't clear on how to use eventInit.

How do i paste text that's in my clipboard into a textbox using userEvent?

This is my code:

test('Copy id button copies correct id', async () => {
  const { getAllByLabelText, debug, getByText } = render(
    <MockedProvider mocks={mocks} addTypename={false}>
      <History />
    </MockedProvider>
  );

  const textbox = <input type="text" />;
  
  await waitFor(() => new Promise((resolve) => setTimeout(resolve, 0)));

  const button = getAllByLabelText('click to copy id')[0];
  fireEvent.click(button);
  // userEvent.paste(textbox,_,) unsure what to do here...
});

Documentation: Documentation

2 Answers

userEvent.paste won't help you: it is meant for cases where you test what happens when a user pastes some text into an input. React testing library doesn't actually have a clipboard that would hold the value that was copied.

What I would do:

  • mock the "copy to clipboard" function, so your test just checks that the correct function is called when the user clicks on the button
  • write a separate unit test for the copy to clipboard functionality (if it makes sense, you'd have to mock a lot of browser apis so manual testing would make sense)

If you actually want to test that copying to clipboard works, you need to write an end to end test that runs an actual browser. At least Cypress offers apis to read the contents of the clipboard.

Another option would be to do something like

test('Pasting fires onPaste event which returns clipboard data', () => {
  const pasted = jest.fn(() => null);
  const changed = jest.fn(() => null);

  render(
    <PasteComponent paste={pasted} changeEvent={changed} data-testid='paste-input' />);

  const PhoneNumberElement = screen.queryByTestId('paste-input');

  const paste = createEvent.paste(PhoneNumberElement, {
    clipboardData: {
      getData: () => '123456',
    },
  });

  fireEvent(PhoneNumberElement, paste);

  expect(pasted).toHaveBeenCalled();
  expect(pasted).toHaveBeenCalledWith('123456');
});

I wrote up a post on it - https://medium.davidendersby.me/2-ways-to-trigger-the-onpaste-event-with-testing-library-1502c5fdb9e

Related