prompt
cy.prompt is an AI-powered Cypress command that turns natural language test steps into executable Cypress commands. This page is the command reference: its signature, the actions it supports, and its limitations.
New to cy.prompt? Start with the AI Test Generation guide, which covers how it works, choosing a workflow, writing effective prompts, self-healing, placeholders, viewing and exporting the generated code, and full examples.
Syntax​
interface PromptCommand {
(
// array of steps to execute
steps: string[],
options?: {
// redacted dynamic inputs that are ignored for cache identity
placeholders?: { [key: string]: string }
}
): void
}
Arguments​
steps (String[])
An array of steps to execute.
options (Object)
Pass in an options object to cy.prompt().
| Option | Default | Description |
|---|---|---|
placeholders | {} | Dynamic or sensitive values that enable caching and are excluded from AI calls. See placeholders for more details. |
Yields ​
cy.prompt() yields the value yielded by the last Cypress command executed in the prompt. In most cases, this will be an element, but it depends on the last command executed in the prompt.
cy.prompt([
// Executes cy.visit('/user-management')
'visit https://cloud.cypress.io/login',
// Executes cy.get('#login-button').click()
'click the login button',
]) // yields <button> since .click() yields the same subject it was originally given.
.closest('form')
.submit()
In the example below, the last command executed in the prompt is .visit(), so the yielded value is the window object.
cy.prompt([
// Executes cy.visit('/user-management')
'visit https://cloud.cypress.io/login',
]) // yields window object since .visit() yields window object
.its('navigator.language')
.should('equal', 'en-US')
Supported actions​
cy.prompt supports the actions below. For guidance on phrasing steps clearly, see Write effective prompts.
Navigate to pages​
'visit https://example.cypress.io'
'navigate to /login' // with baseUrl set
Interact with elements​
Click​
'click the login button'
'hit the "x" button'
'click the button containing "Edit"'
'expand the FAQ section'
'close the Technical Information section'
'switch to the Settings tab'
'force click the submit button'
'double click the product image'
'right click the file item'
Type and inputs​
'type "[email protected]" in the email field'
'type {enter} in the email field'
'write "42" in the number field'
'put "No comment" in the textarea'
'fill the search input with "cypress"'
'force type "text" in the hidden input'
'clear the username field'
'focus on the search input'
'blur the filter input'
Form and controls​
'select "Canada" from the country dropdown'
'pick "United States" from the list'
'choose "Newest" from the suggestions'
'check "I agree"'
'uncheck "Send me updates"'
'toggle the "Dark Mode" switch'
'submit the contact form'
Scroll​
'scroll the sales section into view'
'scroll to todays date in the calendar'
Keyboard, mouse, and other events​
'press "Tab" to focus the next field'
'press "Enter" to choose the current selection'
'hover over the "Help" button'
'trigger a mousemove event on the .bar-chart'
Verify results​
'make sure the confirmation button is visible'
'verify an alert exists'
'expect the notification to contain the text "Email sent"'
'confirm that the [data-cy="result"] element has the text "Success"'
'the toast should not contain the text "Failed"'
'the current URL should be "https://cloud.cypress.io/login"'
'I expect the email field to have the value "[email protected]"'
'verify the "Remember me" input is disabled'
'the "Login" button should be enabled'
'now the product should have the class "loading"'
'assert the "I agree" checkbox is checked'
'validate that the #error-message is empty'
'the "Profile" tab should be active'
'the modal ought to be displayed'
'verify both checkboxes are checked'
'the search input should have focus'
'and "United States" is selected'
'ensure that the counter shows 5'
'verify the counter has the id "reset"'
'confirm that the code frame includes HTML "<span class="token">'
Non-existence assertions​
You can verify that elements do not exist to generate not.exist assertions, but only when you provide an exact CSS selector or when you use text-based targeting. Natural language descriptions for non-existence are not currently supported. Additionally, ensure that your intention is to verify that the element does not exist in the DOM, not that it is not visible.
'verify #error-message does not exist'
'the ".loading-spinner" should not exist'
'make sure the "Error" message does not exist'
'confirm "Reset" button does not exist'
Change the viewport​
'set the viewport to 400x600'
Wait​
Wait for an amount of time or wait for an already aliased intercept to resolve before moving on to the next command in Cypress.
'wait 2 seconds'
'wait 500 milliseconds'
'wait for @customer alias'
'wait for the @users request to finish'
Command options​
'go to "/users" with a timeout of 10 seconds'
'dismiss the modal using a timeout of 6 seconds'
'force click the submit button'
'force click the "Close" button'
'force type "text" in the hidden input field'
'force check the "I agree" checkbox'
'force uncheck the "Send updates" checkbox'
Examples​
Several of these examples use placeholders for dynamic or sensitive values. For the concepts behind these examples, see the AI Test Generation guide.
Gherkin-style tests​
cy.prompt can execute Gherkin-style tests, making test automation accessible to a broader audience including product managers, QA engineers, and stakeholders who are familiar with behavior-driven development (BDD) patterns. This expands the pool of people who can write and maintain tests without requiring deep technical knowledge of Cypress APIs. This is also a great way to get started with test automation and get buy-in from stakeholders who are familiar with BDD patterns.
Benefits for Cucumber users:​
- Familiar syntax: If you're already using Cucumber/Gherkin,
cy.promptaccepts the same Given/When/Then/And structure - No step definitions: Unlike traditional Cucumber, you don't need to write step definition files -
cy.promptinterprets the steps directly - Improved performance: Tests run without the overhead of Cucumber's step definition mapping
- Simplified maintenance: No need to maintain separate step definition files that can become out of sync with your tests
Gherkin example 1: Successful user registration with valid data​
describe('Feature: User Registration', () => {
it('Scenario: Successful user registration with valid data', () => {
cy.prompt(
[
'Given the user is on the "/register" page',
'When the user enters "Avery Lopez" in the name field',
'And the user enters {{password}} in the password field',
'And the user enters {{password}} in the confirm password field',
'And the user selects "admin" from the role dropdown',
'And the user checks the terms and conditions checkbox',
'And the user clicks the "Register User" button',
'Then the user should see a success notification',
'And the user should be added to the user list',
],
{
placeholders: {
password: 'PASSWORD_PLACEHOLDER', // Use cy.env(['PASSWORD']) to get the actual value
},
}
)
})
})
The generated code may look like:
describe('Feature: User Registration', () => {
it('Scenario: Successful user registration with valid data', () => {
// Prompt step 1: Given the user is on the "/register" page
cy.visit('/register')
// Prompt step 2: When the user enters "Avery Lopez" in the name field
cy.get('#full-name').type('Avery Lopez')
// Prompt step 4: And the user enters "password123" in the password field
cy.get('#password').type('password123')
// Prompt step 5: And the user enters "password123" in the confirm password field
cy.get('#confirm-password').type('password123')
// Prompt step 6: And the user selects "admin" from the role dropdown
cy.get('#role').select('admin')
// Prompt step 7: And the user checks the terms and conditions checkbox
cy.get('#terms').check()
// Prompt step 8: And the user clicks the "Register User" button
cy.get('#registration-form .btn-success').click()
// Prompt step 9: Then the user should see a success notification
cy.get('.success').should('be.visible')
// Prompt step 10: And the user should be added to the user list
cy.get('#user-list').should('contain', 'Avery')
})
})
Gherkin example 2: User cannot be deactivated if already inactive​
describe('Feature: User Status Management', () => {
it('Scenario: User cannot be deactivated if already inactive', () => {
cy.visit('/user-management')
cy.prompt([
'Given there is an inactive user on the page',
'When the admin tries to deactivate the already inactive user',
'But the user is already in inactive status',
'Then the system should show a message that user is already inactive',
'But the user status should remain unchanged',
])
})
})
The generated code may look like:
describe('Feature: User Status Management', () => {
it('Scenario: User cannot be deactivated if already inactive', () => {
cy.visit('/user-management')
// Prompt step 1: Given there is an inactive user on the page
cy.get('#user-list .status-inactive').should('be.visible')
// Prompt step 2: When the admin tries to deactivate the already inactive user
cy.get('#user-list div:nth-child(3) > .user-actions > .btn-danger').click()
// Prompt step 3: But the user is already in inactive status
cy.get('#user-list .status-inactive').should('contain', 'inactive')
// Prompt step 4: Then the system should show a warning message
cy.get('.warning-notification').should('be.visible')
// Prompt step 5: But the user status should remain unchanged
cy.get('#user-list .status-inactive').should('contain', 'inactive')
})
})
Gherkin example 3: Admin manages user status​
it('Scenario Outline: Admin manages user status', () => {
cy.visit('/users')
const Examples = [
{ status: 'pending', action: 'activates', new_status: 'active' },
{ status: 'active', action: 'deactivates', new_status: 'inactive' },
{ status: 'inactive', action: 'activates', new_status: 'active' },
]
Examples.forEach((example) => {
cy.prompt([
`Given there is a(n) ${example.status} user on the page`,
`When the admin ${example.action} the user`,
`Then the user status should change to ${example.new_status}`,
])
})
})
The commands in the generated code may look like:

Login flow​
cy.env(['ADMIN_PASSWORD']).then(({ adminPassword }) => {
cy.prompt(
[
'visit the login page',
'type {{password}} in the password field',
'click the login button',
'verify we are redirected to the dashboard',
],
{
placeholders: { password: adminPassword },
}
)
})
E-commerce checkout​
cy.prompt([
'visit https://example.com/products',
'search for "wireless headphones"',
'click on the first search result',
'click the "Add to Cart" button',
'verify the cart icon shows 1 item',
'click the cart icon',
'click the "Proceed to Checkout" button',
'fill in shipping information',
'select standard shipping',
'enter credit card details',
'click the "Place Order" button',
'verify the order confirmation page loads',
])
When cy.prompt resolves the credit card fields in this flow, field values are
automatically excluded before any data is sent to the AI model. See
Sensitive data handling.
Search functionality​
cy.prompt([
'search for "united states"',
'pick "United States" from the list',
'clear the search field',
'look for "canada"',
'choose "Canada" from the suggestions',
])
Settings configuration​
cy.prompt([
'toggle on the "Enable Notifications" switch',
'verify the notification shows "Enable Notifications enabled"',
'verify the notifications toggle is enabled',
'verify the toggle switch is in the on position',
])
Dynamic testing with loops​
If you need to test a loop of steps, you can use the placeholders option to pass in the dynamic values. This optimizes caching so that the prompt does not need to be called out to AI for each iteration of the loop.
const matchingSearchTerms = ['cypress', 'testing', 'automation']
const nonMatchingSearchTerms = ['cyprus', 'fuzzy', 'wrong']
matchingSearchTerms.forEach((term) => {
cy.prompt(
[
`type "{{term}}" in the search input`,
`verify the search results contain "{{term}}"`,
],
{
placeholders: {
term,
},
}
)
})
nonMatchingSearchTerms.forEach((term) => {
cy.prompt(
[
`type "{{term}}" in the search input`,
`verify the search results does not contain "{{term}}"`,
],
{
placeholders: {
term,
},
}
)
})
Cross-origin testing​
cy.origin('https://cloud.cypress.io/login', () => {
cy.prompt(
[
'type {{password}} in the password field',
'click the login button',
],
{
placeholders: {
password: 'PASSWORD_PLACEHOLDER',
},
}
)
})
Mixed with traditional Cypress​
const electronicsCount = Cypress.expose('staging') === true ? 5 : 25
// Confirm the UI works in staging environment
cy.task('seedStagingDB')
cy.visit(`${Cypress.expose('stagingUrl')}/products`)
cy.prompt(
[
'filter by category "Electronics"',
'sort by price high to low',
`verify the product count is {{electronicsCount}}`,
'verify the sort indicator is "Price: High to Low"',
],
{
placeholders: {
electronicsCount,
},
}
)
// Confirm the UI works in production environment
cy.task('seedProductionDB')
cy.visit(`${Cypress.expose('productionUrl')}/products`)
cy.prompt(
[
'filter by category "Electronics"',
'sort by price high to low',
`verify the product count is {{electronicsCount}}`,
'verify the sort indicator is "Price: High to Low"',
],
{
placeholders: {
electronicsCount,
},
}
)
Or to further clean up the cy.prompt call:
const electronicsCount = Cypress.expose('staging') === true ? 5 : 25
const electronicsFilterPrompt = [
'filter by category "Electronics"',
'sort by price high to low',
`verify the product count is {{electronicsCount}}`,
'verify the sort indicator is "Price: High to Low"',
]
// Confirm the UI works in staging environment
cy.task('seedStagingDB')
cy.visit(`${Cypress.expose('stagingUrl')}/products`)
cy.prompt(electronicsFilterPrompt, {
placeholders: {
electronicsCount,
},
})
// Confirm the UI works in production environment
cy.task('seedProductionDB')
cy.visit(`${Cypress.expose('stagingUrl')}/products`)
cy.prompt(electronicsFilterPrompt, {
placeholders: {
electronicsCount,
},
})
Limitations​
These apply to all cy.prompt usage unless noted otherwise.
| Limitation | Details |
|---|---|
| Command Coverage | Not all Cypress APIs supported - see Supported actions |
| Authentication | Requires Cypress Cloud account and/or valid record key |
| Test Type | E2E tests only (component testing not supported) |
| Browser Support | Chromium-based browsers only (Chrome, Edge, Electron) |
| Language Support | Optimized for English prompts; other languages are not guaranteed |
| Assertions | 'not.exist' assertions from natural language are not supported. However, 'not.exist' assertions work when you provide an exact CSS selector (e.g., 'verify #error-message does not exist') or when you use text-based targeting. See issue |
| Multi-Element | Assertions on multiple elements are not currently supported See issue |
| Cookies/Sessions | Clearing cookies or sessions is not supported See issue |
| Scrolling | Scrolling to elements is not supported See issue |
| API Testing | API requests (e.g., cy.request()) is not supported See issue |
| DOM Support | Canvas and iframe elements are not supported. See canvas issue and iframe issue |
For pricing, usage limits, and billing, see the cy.prompt FAQ.
History​
| Version | Changes |
|---|---|
| 15.13.0 | cy.prompt moves to beta. Removed experimentalPromptCommand flag. |
| 15.4.0 | Introduced cy.prompt command |
See also​
- AI Test Generation - for generating tests from natural language
- Cypress Studio - for creating tests in a visual editor and using AI to generate assertions
- ElementSelector API - for customizing how Cypress selects elements in Studio and cy.prompt()