Skip to content

Instantly share code, notes, and snippets.

@nickytonline
Last active June 21, 2024 16:24
Show Gist options
  • Save nickytonline/bcdef8ef00211b0faf7c7c0e7777aaf6 to your computer and use it in GitHub Desktop.
Save nickytonline/bcdef8ef00211b0faf7c7c0e7777aaf6 to your computer and use it in GitHub Desktop.
Simulate a paste event in Cypress
/**
* Simulates a paste event.
*
* @param pasteOptions Set of options for a simulated paste event.
* @param pasteOptions.destinationSelector Selector representing the DOM element that the paste event should be dispatched to.
* @param pasteOptions.pastePayload Simulated data that is on the clipboard.
* @param pasteOptions.pasteFormat The format of the simulated paste payload. Default value is 'text'.
*/
function paste({ destinationSelector, pastePayload, pasteType = 'text' }) {
// https://developer.mozilla.org/en-US/docs/Web/API/Element/paste_event
cy.get(destinationSelector).then($destination => {
const pasteEvent = Object.assign(new Event('paste', { bubbles: true, cancelable: true }), {
clipboardData: {
getData: (type = pasteType) => pastePayload,
},
});
$destination[0].dispatchEvent(pasteEvent);
});
}
@NaserYasar
Copy link

pastePayload, how this value came ??

@erwinvanlun
Copy link

erwinvanlun commented Oct 12, 2023

Inspired by above, this what I have added:

declaration:
paste(input: string | { pastePayload: string; pasteType: string }): Chainable<JQuery<HTMLElement>>;

definition:

/**
 * usages:
 * cy.paste('text to paste') OR:
 * cy.paste({ pastePayload: 'text to paste', pasteType: 'text/plain' })
 */
Cypress.Commands.add('paste', { prevSubject: true }, (subject, pasteInput) => {
  const isSimpleText = typeof pasteInput === 'string';

  const pastePayload = isSimpleText ? pasteInput : pasteInput.pastePayload;
  const pasteType = isSimpleText ? 'text/plain' : pasteInput.pasteType || 'text/plain';

  const data = pasteType === 'application/json' ? JSON.stringify(pastePayload) : pastePayload;

  const clipboardData = new DataTransfer();
  clipboardData.setData(pasteType, data);

  const pasteEvent = new ClipboardEvent('paste', {
    clipboardData
  });
  subject[0].dispatchEvent(pasteEvent);

  return subject;
});

usage
cy.paste('github is great!')
OR

cy.paste({pastePayload: 'text to paste', pasteType: 'text/plain' })

(other types work as well)

@nickytonline
Copy link
Author

Nice one @erwinvanlun!

@IrvingArmenta
Copy link

The cypress command did not work for me.
in Cypress version: 13.8.1

I just ended up writing this simple line for my purpose:

const text = 'text I want to paste in the input';

cy.get('input').eq(0).trigger('paste', {
        clipboardData: { getData: () => text }
});

It is not very "modular" or reusable, but it worked perfectly for my test case.

@nickytonline
Copy link
Author

I haven’t touched or used this command in years so glad you got something working for your tests @IrvingArmenta!

@nnaydenow
Copy link

nnaydenow commented Jun 14, 2024

Hi @IrvingArmenta,

Could you share more about your configuration? I'm using similar setup to yours but it doesn't work.

cy.mount(html`<input />`)

const text = 'text I want to paste in the input';

cy.get('input')
	.eq(0)
	.click()
	.trigger('paste', {
		clipboardData: { getData: () => text }
	});

cy.get("input")
	.should("have.value", text)

@irv-armenta-g
Copy link

irv-armenta-g commented Jun 19, 2024

@nnaydenow
If you only have one <input /> then no need for eq() , you should just select that one input, also my inputs have a custom onPaste
also not sure why you need click()
listener:

// function
const handleOnPaste = (
    e: React.ClipboardEvent<HTMLInputElement>,
    index: number
  ) => {
    e.preventDefault();
    const pastedData = e.clipboardData.getData('text');
    
    // do something with the pastedData, like set as a value to the input
}

// jsx
<input
  type="text"
 onPaste={(e) => handleOnPaste(e, index)}
 />

But in my case is an array of inputs.

@ugljanin
Copy link

Not working for me too. It pastes "internalCopy" as a value.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment