Handling copy and paste in Cypress
Clipboard or pasting text is not available out of the box in Cypress. But as Gleb says: "It's just JavaScript". And he's right. Cypress is pure JavaScript, so you can do anything that JS allows you to do.
Pasting text
Let's look at the first example. I have a very simple app here that has two input fields. The first input field will check the validity of the input. If inserted text is not an email, it will throw an error. By the way, you can check out these examples in my repo on GitHub.
In the simplest form we can paste a text into our email field with the following code:
Instead of typing our text, we are using the .invoke()
command to change our input's value. This way, we are immediately getting into the final state of what our users would experience. You might notice, though, that something is missing from our app:
We do not see our validation message. This is because our validation was not triggered. The reason for that becomes more apparent when we look into the event listeners panel. There are a couple of event listeners bound to this input field.
These event listeners handle our validation. Our input field is not validated until a user clicks away from it or presses the TAB button. This will trigger a blur event and make our input field invalid.
These event listeners are very commonly used with forms. Different frameworks use different approaches to input fields. It is very useful to look into what kind of event listeners are bound into your app elements. It can help you better understand what happens when the user interacts with your input field. In our case, we need to fire the blur
event to our input field:
We can either use .trigger()
command or use .focus()
and .blur()
commands from Cypress to trigger our events. I like to prefer .trigger()
just because it gives you a wider variety of events you can trigger. E.g., in an app that I test for work, there's a compositionend
event that I need to trigger from time to time.
To simulate pasting a text, you often need to mimic a sequence of events that happen over an element you interact with. Fun tip for you: To see your events happen inside your app, open your Chrome console and type in monitorEvents($0)
. The $0
stands for the active element, so make sure you select it via the elements panel first.
Copying to clipboard
Let's now look into the other side of the story. For our next test, we want to copy a text from our textarea
. To make sure this action was successful, we want to test the contents of our clipboard. To do that, we can install a tool called clipboardy and run it as a plugin in Cypress. To setup this plugin, we define a new task in our plugins/index.ts
file:
Now that we have defined our task, we can use it in our test:
Our task will return the content of our clipboard. This enables us to write an assertion, just as we would normally do with any other element.
However, this test will work only if you run your test in Electron. Because our .click()
command is fired with JavaScript, it has an isTrusted
property set to false. Whenever a click event is dispatched or created by a script, it has this property set to it. Cypress uses JavaScript to fire its events, so they differ from real user interaction.
There is a way of firing real click events in Chrome, using cypress-real-events plugin. This plugin adds some real events to your app (it has a hover command, too!). Firing a real event here will copy the desired text to the clipboard.