---
id: api/commands/prompt
title: cy.prompt()
description: >-
  AI-powered Cypress command for developers and QA teams. Generate Cypress tests
  from natural language, get self-healing selectors, and reduce end-to-end test
  maintenance with cy.prompt.
section: api
source_path: docs/api/commands/prompt.mdx
version: 3163d68b20e695f2c76d40c85c3f3b956dd19a3b
updated_at: '2026-08-21T20:59:04.402Z'
---
# 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](/llm/markdown/app/guides/ai-test-generation.md), 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](/llm/markdown/app/guides/ai-test-generation.md#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](/llm/markdown/app/guides/ai-test-generation.md#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 "john.doe@company.com" 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 "anika.mehta@email.com"'
'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](/llm/markdown/app/guides/ai-test-generation.md#Targeting-elements-by-text-content)**. 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](/llm/markdown/app/guides/ai-test-generation.md#Placeholders) for dynamic or sensitive values. For the concepts behind these examples, see the [AI Test Generation guide](/llm/markdown/app/guides/ai-test-generation.md).

### 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.prompt` accepts the same Given/When/Then/And structure
*   **No step definitions**: Unlike traditional Cucumber, you don't need to write step definition files - `cy.prompt` interprets 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 "avery.lopez@example.com" in the email 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 3: And the user enters "avery.lopez@example.com" in the email field
    cy.get('#email').type('avery.lopez@example.com')

    // 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 "user@example.com" in the email field',
      '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](/llm/markdown/app/guides/ai-test-generation.md#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 "may@example.com" in the email field',
      '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](#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](/llm/markdown/app/guides/ai-test-generation.md#Targeting-elements-by-text-content). [See issue](https://github.com/cypress-io/cypress/issues/33274) |
| Multi-Element | Assertions on multiple elements are not currently supported [See issue](https://github.com/cypress-io/cypress/issues/32787) |
| Cookies/Sessions | Clearing cookies or sessions is not supported [See issue](https://github.com/cypress-io/cypress/issues/32810) |
| Scrolling | Scrolling to elements is not supported [See issue](https://github.com/cypress-io/cypress/issues/32789) |
| API Testing | API requests (e.g., `cy.request()`) is not supported [See issue](https://github.com/cypress-io/cypress/issues/32792) |
| DOM Support | Canvas and iframe elements are not supported. See [canvas issue](https://github.com/cypress-io/cypress/issues/32830) and [iframe issue](https://github.com/cypress-io/cypress/issues/32800) |

For pricing, usage limits, and billing, see the [cy.prompt FAQ](/llm/markdown/cloud/faq.md#cyprompt).

## History

| Version | Changes |
| --- | --- |
| [15.13.0](/llm/markdown/app/references/changelog.md#15-13-0) | `cy.prompt` moves to beta. Removed `experimentalPromptCommand` flag. |
| [15.4.0](/llm/markdown/app/references/changelog.md#15-4-0) | Introduced `cy.prompt` command |

## See also

*   [AI Test Generation](/llm/markdown/app/guides/ai-test-generation.md) - for generating tests from natural language
*   [Cypress Studio](/llm/markdown/app/guides/cypress-studio.md) - for creating tests in a visual editor and using AI to generate assertions
*   [ElementSelector API](/llm/markdown/api/cypress-api/element-selector-api.md) - for customizing how Cypress selects elements in Studio and cy.prompt()
