18

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

Noob
  • 754
  • 3
  • 10
  • 27
  • Can you provide your `copy to clipboard` code? – Danny Ouellet Feb 19 '21 at 20:36
  • 1
    there is no need for you to set up an input to paste the content; just mock the function you are calling inside the button you are testing, and check it is being called with the id value, something similar to this question https://stackoverflow.com/questions/61807378/jest-test-for-a-copy-to-clipboard-method-using-react-with-typescript – diedu Feb 21 '21 at 05:21
  • You don't need to paste your clipboard, and you can suppose to the mock text as your clipboard text. `userEvent.paste(getByRole('textbox', { name: /paste your greeting/i }), text)` means mocking your clipboard text in to the targeted textbox. After this paste action you can just check the content of targeted textbox has the mocked text. – James Lin Feb 25 '21 at 12:44

3 Answers3

10

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

Dharman
  • 30,962
  • 25
  • 85
  • 135
Davetherave2010
  • 370
  • 3
  • 9
  • 2
    Awesome article! Although I would strongly recommend switching over to function based components instead of legacy class based components, especially now that we have access to hooks. It's less verbose, simpler, and a more modern/common approach to things. There are several articles on how to / why to (here's a random one - https://dev.to/danielleye/react-class-component-vs-function-component-with-hooks-13dg) – Sergnio May 10 '21 at 21:23
9

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.

OlliM
  • 7,023
  • 1
  • 36
  • 47
2

if you want to simulate a paste event into input you can you using userEvent.paste() method from "@testing-library/user-event";

When you working with library version >= 14

test('Paste event', async () => {
  const { queryByTestId } = render(
    <Input/>
  );

  const input = queryByTestId('your-data-testid');
  //Focus input
  input.focus();
  await userEvent.paste("Text-you-want-to-paste")

  await waitFor(() => {
    expect(input).toHaveValue("Text-you-want-to-paste");
  })
});
Bastek
  • 43
  • 5