There is no way to access the clipboard in a test, as far as I can tell.
There should be an easy way to test what the clipboard holds. Useful for websites where text is placed in the clipboard using JS to transfere it somewhere.
all versions
Related issues
document.execCommand() copy to clipboard: https://github.com/cypress-io/cypress/issues/2851Accessing clipboard can be worked around, but the main issue is that the document.execCommand('copy') doesn't work (as stated above), which I reckon is the primary (and only?) way for your app to programmatically put a text to user's clipboard.
Assuming it happens somehow (or is fixed upstream), the checking the clipboard's contents can be done e.g. by using clipboardy:
npm i -D clipboardy
plugins/index.js:
const clipboardy = require('clipboardy');
module.exports = ( on ) => {
on('task', {
getClipboard () {
return clipboardy.readSync();
}
});
};
In your spec:
describe('test', () => {
it('test', () => {
cy.document().then( doc => {
doc.body.innerHTML = '<input id="inp">';
});
cy.get('#inp').type('test{selectall}');
cy.document().then( doc => {
// this currently doesn't work unless you manually put focus
// into the AUT preview window (e.g. by clicking)
doc.execCommand('copy');
});
cy.task('getClipboard').should('contain', 'test');
});
});
I have a workaround for pasting in the interim. It fits the use case I have for pasting data, so I thought I'd share. See https://gist.github.com/nickytonline/bcdef8ef00211b0faf7c7c0e7777aaf6
Is there a reason why Cypress would block a .click() action when clicking a button that is doing a copy action? I keep getting a growl on our site during test runs and it states "Copy to clipboard not compatible with this browser! Try Chrome!" except, i'm running Cypress with Chrome.
HTML (The formatting might look off, that's just to fit it on screen without a scrollbar):
<a message-element="" class="btn btn-test btn-block btn-sm print-hide ng-isolate-scope" href="javascript:void(0)"
ng-click="copyLink()" title="" data-toggle="tooltip" data-container="body" data-placement="top"
data-original-title="Click to copy">
<i class="fa fa-clipboard"></i> <span class="notranslate" data-cy="detailsLinkButton">Link< /span>
</a>
This fails every time I do a cy.get('[data-cy=detailsLinkButton]').click(); Which prevents me from using clipboardy to verify results.
After the test has run in the Test Runner I can click the button and I'll get the proper green growl that states it's been copied to my clipboard, but it won't work while the test is running. Any ideas?
I originally thought this was an issue with clipboardy, but it works elsewhere on our site, and I eventually stripped clipboardy out of the test entirely just to see what would happen with the click. That's when i found Cypress seems to be blocking the action.
We're currently experiencing the same: You can't copy to clipboard in cypress… in Firefox. In Chrome it seems to work fine.
This could be related to the special handling of copying in Firefox mentioned on can I use.
Writing to the clipboard is available without permission in secure contexts and browser extensions, but only from user-initiated event callbacks. Browser extensions with the "clipboardWrite" permission can write to the clipboard at any time.
As nobody want's to introduce https to the e2e testing stage (I think), maybe cypress could use the mentioned "clipboardWrite" permission in Firefox?
@zepatrik Here's my current approach:
navigator.clipboard.writeText method that your application calls to copy text.This is what that looks like when implemented in Typescript:
describe('My website page', () => {
it('copies signup links to clipboard', () => {
cy.visit(`/${school.id}/users`, {
onBeforeLoad(win: Window): void {
cy.spy(win.navigator.clipboard, 'writeText').as('copy');
},
});
cy.contains('button', 'Share signup link').click();
cy.get('@copy').should('be.calledWithExactly', `http://localhost:3000/${school.id}/signup`);
});
});
Note that this approach doesn't solve every problem. For example, if you use the invisible textarea workaround (for older browsers), I still don't know of any way to assert about the actual content of the system clipboard.
Most helpful comment
Accessing clipboard can be worked around, but the main issue is that the
document.execCommand('copy')doesn't work (as stated above), which I reckon is the primary (and only?) way for your app to programmatically put a text to user's clipboard.Assuming it happens somehow (or is fixed upstream), the checking the clipboard's contents can be done e.g. by using clipboardy:
plugins/index.js:In your spec: