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 cypress.json
).
{% 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:
code
stdout
stderr
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 })
.its('code').should('eq', 1)
.its('stderr').should('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 cypress.json
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.writeFile()
writefile %}