How to paste clipboard data using React Testing Library?
B

4

21

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

Botha answered 10/2, 2021 at 20:43 Comment(3)
Can you provide your copy to clipboard code?Telescope
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 #61807878Olnay
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.Desalvo
M
11

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

Muriate answered 7/5, 2021 at 19:30 Comment(1)
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 - dev.to/danielleye/…)Shoelace
C
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.

Cofsky answered 24/2, 2021 at 12:36 Comment(0)
B
5

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");
  })
});
Beadle answered 30/1, 2023 at 12:6 Comment(0)
D
0
const handleOnPaste = async (e)=>{
        e.preventDefault();
        const timer = ms => new Promise(res => setTimeout(res, ms))
        e.clipboardData.items[0].getAsString(text => {
            let lines = text.split('\n');
            let i = 1;
            lines.forEach(line => {
                let cell = line.split('\t');
                setNewDataInTable((currentState)=>{  
                    // const newState = currentState.map((oneRow)=>{
                    //     if(oneRow.name === cell[0]){
                    //         oneRow.value = String(cell[1]).replace("\r", "")
                    //         return oneRow
                    //     }
                    //     else{ 
                    //         return oneRow
                    //     }
                    // })
                    currentState.map(function(oneRow){
                        if(oneRow.name === cell[0]){
                            oneRow.value = String(cell[1]).replace("\r", "")
                            return oneRow
                        }
                        else{ 
                            return oneRow
                        }
                    })
                    //console.log("newState2",newState)
                    //return newState
                })          
            i++;
            });
        })
        await timer(1000);
    }

could someone help on writing test case for this, here i am doing copy paste ,pasting key value pair ,so that clipboard key value is compared to table first column data if matches then value is pasted in 2nd column.
ex: my Table having
    FruitName Quantity
    Apple     
    Mango

in Excel i am having(data separated by tab)copying this data and pasting in my react application 2nd column.
 Apple   3kg
 Bannana 5kg
 Mango   4kg
Darcydarda answered 10/6 at 9:36 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Genesisgenet

© 2022 - 2024 — McMap. All rights reserved.