Let's take an example application that copies some text to the system clipboard when the user clicks a button.
🎁 You can find the source code for this blog post in the repo bahmutov/test-api-example.
The application code for that button formats the string and calls the clipboard.writeText
browser API method.
1 | async copyTodos({ state }) { |
The clipboard.writeText
is a security-restricted method. To prevent malicious JavaScript from stealing your information, sending a synthetic "Click" event to the button for example fails if the browser window does not have focus (meaning the user did not click it).
Calling the clipboard.writeText
method is the problem. We can stub it from a Cypress test using the included cy.stub command.
1 | cy.window() |
Now the test runs correctly in all situations.
By checking if the clipboard.writeText
method was really called, our test can catch any drastic changes to the application.
Resolve the promise
The clipboard.writeText
method definition returns a Promise<void>
. The application code might attach a .catch(err)
callback to that promise. Thus the test code needs to return a Promise instance. We can do this using the Sinon helper .resolve()
1 | cy.stub(clipboard, 'writeText').as('writeText').resolves() |
Update 1: document.execCommand
Modern applications sometimes use an older deprecated method of copying text into the clipboard via document.execCommand. This command is really cumbersome to use. For example, to copy text to the clipboard we have to create a hidden text area, put the text there, select it, and then execute the command. Then we need to remove the text area element:
1 | // app.js |
Our test might spy / stub the document.execCommand
method when called with the copy
parameter.
1 | // cypress/e2e/clipboard.cy.ts |
But how do we get the copied text? Well, assuming you want to use the deprecated method, need the copied text, and do not want to access the real system clipboard, you could simply pass the text when calling the method.
1 | // app.js |
Let's check the text
1 | // cypress/e2e/clipboard.cy.ts |
See also
- Stubs, spies, and clock examples
- My course Cypress Plugins shows how to click the "Copy to clipboard" button using a native click event by using the cypress-real-events plugin.