Cypress: implement modifier effects for copy and paste

Created on 22 Aug 2018  路  19Comments  路  Source: cypress-io/cypress

Is this a Feature or Bug?

Feature

Current behavior:

cy.get('input').type('{cmd}c') types in character 'c' instead of simulating copy event.
cy.get('input').type('{cmd}v') types in character 'v' instead of simulating paste event.

Desired behavior:

cy.get('input').type('{cmd}c') simulates copy event.
cy.get('input').type('{cmd}v') simulates paste event.

Versions

Cypress- 3.1.0, operating system- MacOS Sierra 10.12.6, browser- Chrome 68.0.3440.84

pkdriver ready for work native events feature

Most helpful comment

I need a way to test copy/paste in my app. Has any progess been made on this?

All 19 comments

FYI, I got these when trying document.execCommand in the developer tools console (Running Electron 59):

> document.execCommand('copy')
> true
> document.execCommand('paste')
> true
> document.execCommand('undo')
> false
> document.execCommand('redo')
> false

Related to

I need a way to test copy/paste in my app. Has any progess been made on this?

Anu update on this issue?

This issue is still in the 'ready for work' stage, which means no work has been done on this issue as of today, so we do not have an estimate on when this will be delivered.

i tried to implement in the next way

const field = () => cy.get(`input[name="field"]`); 
        it("Invalid chars pasted in", () => {
          field().then((list) => {
            const $el = list[0];

            function copyToClipboard(text) {
              var dummy = document.createElement("textarea");
              document.body.appendChild(dummy);
              dummy.value = text;
              dummy.focus();

              navigator.clipboard.writeText('Text to be copied')
                .then(() => {
                  dummy.focus();
                  console.log('Text copied to clipboard');
                })
                .catch(err => {
                  // This can happen if the user denies clipboard permissions:
                  console.error('Could not copy text: ', err);
                })
                .finally(_ => {
                  document.body.removeChild(dummy)
                })


              // document.execCommand("copy");
            }

            debugger;
            copyToClipboard('123.123123132');

            document.addEventListener('paste', event => {
              event.preventDefault();
              $el.focus();
              debugger;
              navigator.clipboard.readText().then(text => {
                $el.focus();
                console.log('Pasted text: ', text);
              });
            });
            $el.focus();
            debugger;

            navigator.clipboard.readText()
              .then(text => {
                $el.focus();
                console.log('Pasted content: ', text);
              })
              .catch(err => {
                console.error('Failed to read clipboard contents: ', err);
              });

            // const paste = new ClipboardEvent('paste');
            // document.execCommand('paste');
            // window.dispatchEvent(paste);
            // copyPageUrl();
          });
          field().should('have.value', '123.123123132');
        });

Also i tried do it through execCommand / dispatchEvent but neither is working.
Maybe my _try-catch_ helps to clearify the problem source because it throws an error _DOMException: Document is not focused._

Screenshot from 2020-02-12 10-11-11

Also i forsee the problem with Copy-Paste browser permission and asked a question
how set chrome permission in Cypress project

Any updates on this issue?

We are also waiting for this command to get it working

Should this works fine instead of type({cmd} v)

/**
 * 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);
    });
}

https://gist.github.com/nickytonline/bcdef8ef00211b0faf7c7c0e7777aaf6

Understand that you are working on the access the clipboard.

But, {shift} + v does not require clipboard. If this gets working I am sure {ctrl} + v will also work. Because from our code we have the data to the clipboard. But, the only thing we need to implement is press {ctrl} + v.

Trigger this combinations will put the copied text into the input. we have tested this manually.

So, if you can give the solution to trigger the combinations of keys that would be great.

thanks in advance

@Prashant-Kan I'd have to know more specifically how youe 'paste' is implemented. If it's not using the native OS paste and is instead triggered to listen to events on the input of shift + v key, Cypress will fire the appropriate events for the shift + v key used during cy.type().

Have you implemented your own paste? Or are you relying on the OS's paste functionality? The latter will not work in Cypress.

I don't understand, what if I just want to type capital letter with {shift}, why is that not possible?

Any news?

I've confirmed that the COPY portion of the test is working because I can paste manually into notepad and get the expected text.

The problem is that Cypress can't access the clipboard and therefore can't type() what's in it.

We REALLY need this test function ASAP.

@gstlawre : Agree, with you. We have the same thing, Over Copy button is working fine and its storing the data to the clipboard. But the thing is we need to Paste to other TextArea using key combition of Ctrl + V or shift + insert or any other paste shortcut. So, that it will get the data from the clipboard. but cypress has limitation as of now,

I would be great if Cypress starts reading from the clipboard (of OS) we are really waiting for this function.

@Prashant-Kan I'd have to know more specifically how youe 'paste' is implemented. If it's not using the native OS paste and is instead triggered to listen to events on the input of shift + v key, Cypress will fire the appropriate events for the shift + v key used during cy.type().

Have you implemented your own paste? Or are you relying on the OS's paste functionality? The latter will not work in Cypress.

Out Copy-Paste functionality is implement like
-> We have a button of CopyToClipboard which will copy all the text/content written in one textarea. Its working fine we have tested by opening any notepad or navigating to any other TextArea and Pasting by Key combinations or from any OS'menu

But, when tried to do with Cypress its not working. Would be happy if this gets implement at the earliest.

@Prashant-Kan I'd have to know more specifically how youe 'paste' is implemented. If it's not using the native OS paste and is instead triggered to listen to events on the input of shift + v key, Cypress will fire the appropriate events for the shift + v key used during cy.type().
Have you implemented your own paste? Or are you relying on the OS's paste functionality? The latter will not work in Cypress.

Out Copy-Paste functionality is implement like
-> We have a button of CopyToClipboard which will copy all the text/content written in one textarea. Its working fine we have tested by opening any notepad or navigating to any other TextArea and Pasting by Key combinations or from any OS'menu

But, when tried to do with Cypress its not working. Would be happy if this gets implement at the earliest.

This is my test code:

_it('pastes the copied invite', () => {
    cy.get("button[id='... proprietary content removed ...']").focus()
    cy.document().then( doc => {
        doc.body.innerHTML = '<input id="inp" style="width: 600px">'
    });
    cy.get('#inp').type('{ctrl}v').should('have.text', '')
})_

I've used all the aliases for "ctrl" ... none work. They just type the letter "v".

cy.get('#cm_textarea') .type('{ctrl}v', {force: true})

In my way it works properly when I added {force: true}

I've confirmed that the COPY portion of the test is working because I can paste manually into notepad and get the expected text.

The problem is that Cypress can't access the clipboard and therefore can't type() what's in it.

We _REALLY_ need this test function ASAP.

Hi @gstlawre ! How did you make Cypress to copy text?
I use {selectall} for selection, and then I'm not able to copy it.

Was this page helpful?
0 / 5 - 0 ratings