| title | exec |
|---|
Execute a system command.
{% note warning 'Anti-Pattern' %}
Don't try to start a web server from cy.exec().
Read about {% url 'best practices' best-practices#Web-Servers %} here. {% endnote %}
cy.exec(command)
cy.exec(command, options){% fa fa-check-circle green %} Correct Usage
cy.exec('npm run build'){% fa fa-angle-right %} command (String)
The system command to be executed from the project root (the directory that contains the default cypress.json configuration file).
{% fa fa-angle-right %} options (Object)
Pass in an options object to change the default behavior of cy.exec().
| Option | Default | Description |
|---|---|---|
log |
true |
{% usage_options log %} |
env |
{} |
Object of environment variables to set before the command executes (e.g. {USERNAME: 'johndoe'}). Will be merged with existing system environment variables |
failOnNonZeroExit |
true |
whether to fail if the command exits with a non-zero code |
timeout |
{% url execTimeout configuration#Timeouts %} |
{% usage_options timeout cy.exec %} |
cy.exec() yields an object with the following properties:
codestdoutstderr
cy.exec() provides an escape hatch for running arbitrary system commands, so you can take actions necessary for your test outside the scope of Cypress. This is great for:
- Running build scripts
- Seeding your test database
- Starting processes
- Killing processes
cy.exec('npm run build').then((result) => {
// yields the 'result' object
// {
// code: 0,
// stdout: "Files successfully built",
// stderr: ""
// }
})cy.exec('rake db:seed').its('code').should('eq', 0)cy.exec('npm run my-script').its('stdout').should('contain', 'Done running the script')cy.server()
cy.route('POST', '/comments').as('postComment')
cy.get('.add-comment').click()
cy.wait('@postComment').then((xhr) => {
cy.exec(`echo ${JSON.stringify(xhr.responseBody)} >cypress/fixtures/comment.json`)
cy.fixture('comment.json').should('deep.eq', xhr.responseBody)
})You can increase the time allowed to execute the command, although we don't recommend executing commands that take a long time to exit.
Cypress will not continue running any other commands until cy.exec() has finished, so a long-running command will drastically slow down your test cycle.
// will fail if script takes longer than 20 seconds to finish
cy.exec('npm run build', { timeout: 20000 })cy.exec('man bear pig', { failOnNonZeroExit: false }).then((obj) => {
expect(obj.code).to.eq(1)
expect(obj.stderr).to.contain('No manual entry for bear')cy.exec('echo $USERNAME', { env: { USERNAME: 'johndoe' } })
.its('stdout').should('contain', 'johndoe')cy.exec() does not support commands that don't exit, such as:
- Starting a
rails server - A task that runs a watch
- Any process that needs to be manually interrupted to stop
A command must exit within the execTimeout or Cypress will kill the command's process and fail the current test.
{% requirements exec cy.exec %}
{% assertions once cy.exec %}
{% timeouts exec cy.exec %}
List the contents of the default cypress.json configuration file
if (Cypress.platform === 'win32') {
cy.exec('print cypress.json')
.its('stderr').should('be.empty')
} else {
cy.exec('cat cypress.json')
.its('stderr').should('be.empty')
}The command above will display in the Command Log as:
{% imgTag /img/api/exec/exec-cat-in-shell.png "Command Log exec" %}
When clicking on the exec command within the command log, the console outputs the following:
{% imgTag /img/api/exec/console-shows-code-shell-stderr-and-stdout-for-exec.png "console.log exec" %}
- {% url
cy.readFile()readfile %} - {% url
cy.request()request %} - {% url
cy.task()task %} - {% url
cy.writeFile()writefile %}