diff --git a/cypress.config.ts b/cypress.config.ts
index 2ff3cead21..3f90e8524e 100644
--- a/cypress.config.ts
+++ b/cypress.config.ts
@@ -13,7 +13,6 @@ export default defineConfig({
openMode: 0,
},
e2e: {
- experimentalStudio: true,
supportFile: false,
baseUrl: "http://localhost:3000",
setupNodeEvents(on, config) {
diff --git a/docs/api/commands/prompt.mdx b/docs/api/commands/prompt.mdx
new file mode 100644
index 0000000000..e0d2d9c2ab
--- /dev/null
+++ b/docs/api/commands/prompt.mdx
@@ -0,0 +1,779 @@
+---
+title: 'cy.prompt() - Generate Cypress Tests with Natural Language and AI'
+description: Generate Cypress tests from plain English using AI. Automate test creation, reduce maintenance, and enable self-healing with cy.prompt.
+sidebar_label: prompt
+slug: /api/commands/prompt
+e2eSpecific: true
+sidebar_custom_props: { 'new_label': true }
+---
+
+
+
+:::warning
+
+`cy.prompt` is currently invite-only. [Request access](https://on.cypress.io/cy-prompt-early-access?utm_source=docs.cypress.io&utm_medium=prompt-command&utm_content=Request-access) to get early access.
+
+:::
+
+# prompt
+
+`cy.prompt` is a Cypress command that uses AI to convert natural language test steps into executable Cypress tests. It's designed to be flexible - you can use it to quickly generate tests and commit them to source control, or keep it running continuously for self-healing tests that adapt to your app's changes. You can choose the workflow that fits your project's needs.
+
+:::note
+
+Before you start coding with `cy.prompt`
+
+- [How it works](#How-it-works) — understand the AI-powered process behind `cy.prompt`
+- [Choosing your workflow](#Choose-your-workflow) — decide between one-time generation or continuous self-healing
+- [How to write effective prompts](#How-to-write-effective-prompts) — craft clear, reliable natural language steps
+- [What you can do](#What-you-can-do) — explore supported actions and capabilities
+- [Setup](#Setup) — enable the command and configure authentication
+
+:::
+
+
+
+_The demo above shows `cy.prompt` in action with [Cypress Studio](/app/guides/cypress-studio)._
+
+## Syntax
+
+```typescript
+interface PromptCommand {
+ (
+ steps: string[], // array of steps to execute
+ options?: {
+ placeholders?: { [key: string]: string } // redacted dynamic inputs that are ignored for cache identity
+ }
+ ): 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 high performance caching. See [placeholders](#Placeholders) for more details. |
+
+
+
+`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.
+
+```javascript
+cy.prompt([
+ // Executes cy.visit('/user-management')
+ 'visit https://cloud.cypress.io/login',
+ // Executes cy.get('#login-button').click()
+ 'click the login button',
+]) // yields 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.
+
+```javascript
+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')
+```
+
+## How it works
+
+When you call `cy.prompt`, Cypress performs a multi-step process:
+
+1. **Interpret prompt:** Each string in your `steps[]` array is parsed using an AI model. Cypress maps the intent (e.g. 'click the login button') to Cypress commands (`cy.get(...).click()`) and target elements.
+
+2. **Generate selectors:** Cypress evaluates your app's DOM and picks a selector based on priority rules (unique identifiers that are likely to be stable).
+
+3. **Generate Cypress code:** Commands are generated and executed in sequence. The Command Log shows both your natural language step and the commands Cypress ran.
+
+4. **Cache for speed:** Generated code is cached. Re-running the same test does not re-call the AI model unless the prompt or DOM changes in a way that invalidates the cached code.
+
+5. **Self-heal if needed:** If cached selectors fail (element renamed, attributes changed, etc.), Cypress regenerates code for that step. This 'self-healing' happens automatically on future attempts.
+
+6. **Choose your workflow:** `cy.prompt` supports two flexible workflows depending on your project needs.
+ - **Export the code** - Save generated code to your test file for predictable, version-controlled tests
+ - **Keep it running** - Let `cy.prompt` continue to self-heal and adapt to changes
+
+## Choose your workflow
+
+`cy.prompt` supports two flexible workflows depending on your project needs. Both workflows give you full visibility into what code was generated, so you can always inspect and modify the results.
+
+### Workflow 1: Generate once, commit to source control
+
+Use `cy.prompt` to generate tests, then export and commit the code.
+
+#### Why choose this workflow?
+
+- **Predictable execution** - You know exactly what code runs every time
+- **Fast test generation** - Use AI to quickly create test skeletons
+- **No AI dependency** - Tests run without calling the AI service
+- **PR review friendly** - Generated code fits into existing review processes
+- **Stable selectors** - Your app has stable, predictable elements
+
+#### Example
+
+```typescript
+// Generate the test
+cy.prompt(
+ [
+ 'visit https://cloud.cypress.io/login',
+ '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: 'secret123' },
+ }
+)
+```
+
+Use the **Get code** button to view the generated Cypress code. This will display the generated code in a dialog where you can preview what Cypress generated from your prompt. You can save the code to your test file, commit it to your version control system, or copy it to your clipboard.
+
+
+
+### Workflow 2: Continuous AI-powered testing
+
+Keep `cy.prompt` in your tests and let it self-heal and adapt to changes.
+
+#### Why choose this workflow?
+
+- **Self-healing selectors** - Tests adapt when your app changes
+- **Less maintenance** - No need to update tests for every UI change
+- **Dynamic content friendly** - Works well with changing data
+- **Smart regeneration** - AI handles selector failures automatically
+- **Rapid iteration** - Perfect for apps in active development
+
+#### Example
+
+```typescript
+// Let cy.prompt run on every test execution
+cy.prompt([
+ 'visit the product catalog',
+ 'filter by category "Electronics"',
+ 'sort by price high to low',
+ 'verify the product count is 25',
+])
+```
+
+## How to write effective prompts
+
+:::note
+
+**Language Support:** `cy.prompt` is optimized for English prompts and provides the most reliable results when prompts are written in English. We cannot guarantee accuracy or provide support for non-English prompts.
+
+:::
+
+Prompt clarity determines reliability. Follow these rules:
+
+- **Imperative voice**: Start with an action (click, type, verify).
+- **Use absolute URLs**: Use the full URL of the page you want to visit.
+- **One action per step**: Avoid chaining multiple actions in one string.
+- **Avoid ambiguity**: Specify the action or element explicitly. Wrap specific text, values, or identifiers in quotes to help the AI identify them as exact matches. For example, `click the "Submit" button` is clearer than `click the Submit button`.
+- **Include context**: `click the login button in the header` is better than `click login button`.
+
+### Example: Good vs. poor steps
+
+```javascript
+// ✅ Good - clear and descriptive
+cy.prompt([
+ 'visit https://cloud.cypress.io/users/settings',
+ 'click the "Edit Profile" button',
+ 'type "John Doe" in the name field',
+ 'type "john.doe@example.com" in the email field',
+ 'click the "Save Changes" button',
+ 'verify the success message "Profile updated successfully" appears',
+])
+
+// ❌ Poor - vague and error-prone
+cy.prompt([
+ 'go to profile',
+ 'click button',
+ 'type name',
+ 'type email',
+ 'save',
+ 'check success',
+])
+```
+
+### If Cypress cannot interpret a step
+
+If Cypress cannot interpret a step, you'll see a dialog prompting you to refine your prompt. Fill out each step that needs information with a more specific prompt and click **Save** to update the `cy.prompt` code within your test file. The test will then run with the new prompt.
+
+
+
+## What you can do
+
+### Navigate to pages
+
+```javascript
+'visit https://example.cypress.io'
+'navigate to /login' // with baseUrl set
+```
+
+### Interact with elements
+
+```javascript
+'click the login button'
+'hit the "x" button'
+'expand the FAQ section'
+'close the Technical Information section'
+'switch to the Settings tab'
+'dismiss the modal'
+'double click the product image'
+'right click the file item'
+'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"'
+'clear the username field'
+'focus on the search input'
+'blur the filter input'
+'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'
+```
+
+### Verify results
+
+```javascript
+'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 "'
+```
+
+### Wait
+
+```javascript
+'wait 2 seconds'
+'wait 500 milliseconds'
+```
+
+## Placeholders
+
+### The caching problem
+
+`cy.prompt` works by caching your prompt steps so it doesn't need to reach out to the AI every time. This makes tests run faster, but there's a challenge: **any change to your prompt steps invalidates the cache**, forcing a new AI call.
+
+This becomes problematic when you have **dynamic values** that change each time cy.prompt is run (like timestamps, user IDs, or randomly generated data)
+
+Without placeholders, the cache would always be invalidated because these dynamic values would be hardcoded directly in your steps.
+
+### The placeholder solution
+
+Placeholders let you use dynamic and sensitive values while maintaining cache efficiency:
+
+- **Cache-friendly**: Changes to placeholder values don't invalidate the cache
+- **Runtime substitution**: `{{placeholder}}` syntax gets replaced with actual values at execution time
+- **Privacy-protected**: Placeholder values are never sent to AI services, keeping sensitive data secure
+
+### Example usage
+
+```typescript
+describe('Campaign Management', () => {
+ it('creates multiple campaigns with different discount percentages', () => {
+ const adminPassword = Cypress.env('ADMIN_PASSWORD')
+
+ const campaigns = [
+ { name: 'Fall Sale', discountPct: 10 },
+ { name: 'Spring Sale', discountPct: 15 },
+ ]
+
+ // This loop demonstrates the caching benefit:
+ // - First iteration: AI generates and caches the code
+ // - Subsequent iterations: Reuse cached code with different placeholder values
+ campaigns.forEach((campaign) => {
+ const campaignName = campaign.name
+ const campaignDiscountPct = campaign.discountPct
+
+ cy.prompt(
+ [
+ `Visit ${Cypress.env('ADMIN_URL')}/admin/login`,
+ // Using {{adminPassword}} prevents this sensitive value from being sent to AI
+ 'Type {{adminPassword}} into the password field',
+ 'Click Sign In',
+ 'Open the Promotions tab',
+ 'Click to create a new campaign',
+ // Using {{campaignName}} and {{campaignDiscountPct}}
+ // allows for high performance caching with different values
+ 'Type {{campaignName}} into the name field',
+ 'Set discount to {{campaignDiscountPct}}% for all products',
+ 'Save the campaign',
+ 'Verify the campaign "{{campaignName}}" appears in the list',
+ ],
+ {
+ placeholders: {
+ adminPassword,
+ campaignName,
+ campaignDiscountPct,
+ },
+ }
+ )
+ })
+ })
+})
+```
+
+## Setup
+
+### Enable the command
+
+`cy.prompt` is experimental and may change in future releases. Enable the command in your config file:
+
+:::cypress-config-example
+
+```ts
+{
+ e2e: {
+ experimentalPromptCommand: true,
+ },
+}
+```
+
+:::
+
+### Authentication & usage
+
+Because `cy.prompt` uses AI under the hood, it needs to communicate securely with large language models to interpret your prompts. Cypress Cloud helps manage those requests, apply organization-level controls, and track usage in a way that's non-invasive. We never use your prompts to train AI models, and you can turn AI features off at any time. `cy.prompt` is currently available on any of our [Cypress Cloud plan types](https://www.cypress.io/pricing).
+
+**To use `cy.prompt`, you must either:**
+
+- Log into Cypress Cloud
+- Or run with `--record` and a valid `--key`. See [instructions](/cloud/get-started/setup).
+
+**If you don't have a Cloud account, create a free account and gain access to a 2-week trial of all paid features.**
+
+
+
+
+
+## Examples
+
+### 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
+
+```javascript
+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: Cypress.env('PASSWORD'),
+ },
+ }
+ )
+ })
+})
+```
+
+The generated code may look like:
+
+```javascript
+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
+
+```javascript
+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:
+
+```javascript
+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
+
+```javascript
+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
+
+```javascript
+const password = Cypress.env('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 },
+ }
+)
+```
+
+### E-commerce checkout
+
+```javascript
+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',
+])
+```
+
+### Search functionality
+
+```javascript
+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
+
+```javascript
+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.
+
+```javascript
+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
+
+```javascript
+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: Cypress.env('PASSWORD'),
+ },
+ }
+ )
+})
+```
+
+### Mixed with traditional Cypress
+
+```javascript
+const electronicsCount = 25
+
+// Confirm the UI works in desktop view
+cy.viewport(1024, 768)
+cy.visit(`${Cypress.env('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"',
+])
+
+// Confirm the UI works in mobile view
+cy.viewport(400, 600)
+cy.visit(`${Cypress.env('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"',
+])
+```
+
+Or to further clean up the `cy.prompt` call:
+
+```javascript
+const electronicsCount = 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 desktop view
+cy.viewport(1024, 768)
+cy.visit(`${Cypress.env('stagingUrl')}/products`)
+cy.prompt(electronicsFilterPrompt)
+
+// Confirm the UI works in mobile view
+cy.viewport(400, 600)
+cy.visit(`${Cypress.env('stagingUrl')}/products`)
+cy.prompt(electronicsFilterPrompt)
+```
+
+## Limitations
+
+| Limitation | Details |
+| ---------------- | ------------------------------------------------------------------------ |
+| Authentication | Requires Cypress Cloud account and/or valid record key |
+| Test Type | E2E tests only (component testing not yet 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 are not supported |
+| DOM Support | Canvas elements are not supported |
+| Command Coverage | Not all Cypress APIs supported - see [What you can do](#What-you-can-do) |
+
+## Pricing & usage limits
+
+During the experimental release, access will be provided at no additional charge. Users are limited by the number of `cy.prompt` definitions and steps they can run per hour. This limit is higher for paid accounts and lower for free accounts. Our intention is to not limit normal usage of the feature.
+
+:::note
+
+Please note that pricing and usage limitations are subject to future adjustments. We commit to keeping you informed of any such changes.
+
+:::
+
+### Usage limits
+
+_Usage limits only apply to runs that are not recording to Cypress Cloud._
+
+**User limits on projects with free accounts:**
+
+- 100 prompts per hour
+- 500 prompt steps per hour
+
+**User limits on projects with paid accounts (or on free trial):**
+
+- 600 prompts per hour
+- 3,000 prompt steps per hour
+
+## Privacy & security
+
+For detailed information about how Cypress protects your data and manages AI model security, see our [Security & Compliance page](https://www.cypress.io/security).
+
+## Disabling AI features
+
+AI capabilities, including `cy.prompt`, are enabled by default for all users on any Cloud plan. Organization admins and owners can enable and disable the AI capabilities for their entire organization from their organization settings. For more information, see [our FAQ](/cloud/faq#Are-all-Cloud-AI-capabilities-enabled-by-default-How-can-I-turn-them-off).
+
+## History
+
+| Version | Changes |
+| ------------------------------------------ | ------------------------------------------- |
+| [15.4.0](/app/references/changelog#15-4-0) | Introduced experimental `cy.prompt` command |
+
+---
+
+## See also
+
+- [Cypress Studio](/app/guides/cypress-studio)
diff --git a/docs/api/table-of-contents.mdx b/docs/api/table-of-contents.mdx
index 3eb8becefb..8e5f8b8681 100644
--- a/docs/api/table-of-contents.mdx
+++ b/docs/api/table-of-contents.mdx
@@ -140,6 +140,7 @@ Cypress has a variety of additional commands to help write tests.
| [`.origin()`](/api/commands/origin) | Visit multiple domains of different origin in a single test. |
| [`.pause()`](/api/commands/pause) | Pause test execution, allowing interaction with the application under test before resuming. |
| [`.press()`](/api/commands/press) | Trigger native key events in your application to simulate real user keyboard interactions. |
+| [`.prompt()`](/api/commands/prompt) | Use natural language to generate Cypress tests with AI. |
| [`.readFile()`](/api/commands/readfile) | Read a file from disk. |
| [`.reload()`](/api/commands/reload) | Reload the page. |
| [`.request()`](/api/commands/request) | Make an HTTP request. |
diff --git a/docs/app/guides/cypress-studio.mdx b/docs/app/guides/cypress-studio.mdx
index 3c436540d2..f37ae27d04 100644
--- a/docs/app/guides/cypress-studio.mdx
+++ b/docs/app/guides/cypress-studio.mdx
@@ -37,19 +37,10 @@ Instead of manually typing every `.get()`, `.click()`, or `.type()` command, you
:::success
-1. **Enable Studio:**
- Add to your `cypress.config.js` (Cypress Studio is currently experimental):
-
- ```js
- {
- e2e: {
- experimentalStudio: true
- }
- }
- ```
-
-2. **Run a Spec:**
- Open Cypress, run a spec file, and click New Test or Edit in Studio.
+1. **Run a Spec:**
+ Open Cypress and run a spec file
+2. **Open Studio:**
+ Click Edit in Studio on a test in the Command Log or click Studio Beta in the Studio panel.
3. **Interact & Save:**
Click, type, and right-click to add assertions. Click Save to save your test.
diff --git a/docs/app/references/changelog.mdx b/docs/app/references/changelog.mdx
index 052827fb09..588e130dfd 100644
--- a/docs/app/references/changelog.mdx
+++ b/docs/app/references/changelog.mdx
@@ -8,6 +8,36 @@ sidebar_label: Changelog
# Changelog
+## 15.4.0
+
+_Released 10/7/2025_
+
+**Features:**
+
+- Cypress Studio is now available by default. You no longer have to set the `experimentalStudio` flag. Addresses [#30997](https://github.com/cypress-io/cypress/issues/30997). Addressed in [#32571](https://github.com/cypress-io/cypress/pull/32571).
+- An option is now available to 'Hide HTTP Requests' in the Cypress Command Log. This can be found in the new dropdown menu at the top of the Command Log. Addresses [#7362](https://github.com/cypress-io/cypress/issues/7362). Addressed in [#32658](https://github.com/cypress-io/cypress/pull/32658).
+- Added the `--posix-exit-codes` flag for the `run` command. When this flag is passed, Cypress will exit with 1 if any tests fail, rather than the number of failed tests. Addresses [#32605](https://github.com/cypress-io/cypress/issues/32605) and [#24695](https://github.com/cypress-io/cypress/issues/24695). Addressed in [#32609](https://github.com/cypress-io/cypress/pull/32609).
+- [`cy.prompt()`](/api/commands/prompt) is now a reserved Cypress command, currently gated behind a feature flag that requires an invite from Cypress. This means any custom commands named 'prompt' will no longer work. Stay tuned for updates on when this feature will become more widely available. Addresses [#31826](https://github.com/cypress-io/cypress/issues/31826).
+
+**Bugfixes:**
+
+- Fixed a regression introduced in [`15.0.0`](#15-0-0) where `dbus` connection error messages appear in docker containers when launching Cypress. Fixes [#32290](https://github.com/cypress-io/cypress/issues/32290).
+- Fixed code frames in [`cy.origin()`](/api/commands/origin) so that failed commands will show the correct line/column within the corresponding spec file. Addressed in [#32597](https://github.com/cypress-io/cypress/pull/32597).
+- Fixed Cypress cloud requests so that they properly verify SSL certificates. Addressed in [#32629](https://github.com/cypress-io/cypress/pull/32629).
+
+**Misc:**
+
+- Added a dropdown menu in the Command Log that includes actions like Open in IDE and Add New Test in Studio, along with test preferences such as Auto-Scroll and Hide HTTP Requests. Addresses [#32556](https://github.com/cypress-io/cypress/issues/32556) and [#32558](https://github.com/cypress-io/cypress/issues/32558). Addressed in [#32611](https://github.com/cypress-io/cypress/pull/32611).
+- Updated the Studio test editing header to include a Back button. This change ensures the Specs button remains functional for expanding or collapsing the specs panel. Addresses [#32556](https://github.com/cypress-io/cypress/issues/32556) and [#32558](https://github.com/cypress-io/cypress/issues/32558). Addressed in [#32611](https://github.com/cypress-io/cypress/pull/32611).
+- Fixed the Studio panel resizing when dragging. Addressed in [#32584](https://github.com/cypress-io/cypress/pull/32584).
+- The Next button now maintains consistent visibility during stepping sessions when using `cy.pause`, staying visible but disabled when no immediate next command is available, providing clear visual feedback to users about stepping state. Addresses [#32476](https://github.com/cypress-io/cypress/issues/32476). Addressed in [#32536](https://github.com/cypress-io/cypress/pull/32536).
+
+**Dependency Updates:**
+
+- Upgraded `electron` from `36.8.1` to `37.6.0`. Addressed in [#32607](https://github.com/cypress-io/cypress/pull/32607).
+- Upgraded bundled Node.js version from `22.18.0` to `22.19.0`. Addressed in [#32607](https://github.com/cypress-io/cypress/pull/32607).
+- Upgraded bundled Chromium version from `136.0.7103.177` to `138.0.7204.251`. Addressed in [#32607](https://github.com/cypress-io/cypress/pull/32607).
+
## 15.3.0
_Released 9/23/2025_
diff --git a/docs/app/references/command-line.mdx b/docs/app/references/command-line.mdx
index 1ec960a2b7..c59a92ed42 100644
--- a/docs/app/references/command-line.mdx
+++ b/docs/app/references/command-line.mdx
@@ -217,6 +217,7 @@ cypress run [options]
| `--no-runner-ui` | [Hides the Cypress Runner UI](#cypress-run-no-runner-ui) |
| `--parallel` | [Run recorded specs in parallel across multiple machines](#cypress-run-parallel) |
| `--port`,`-p` | [Override default port](#cypress-run-port-lt-port-gt) |
+| `--posix-exit-codes` | [Exit with a POSIX-compliant exit code](#cypress-run-posix-exit-codes) rather than the number of failed tests. |
| `--project`, `-P` | [Path to a specific project](#cypress-run-project-lt-project-path-gt) |
| `--quiet`, `-q` | [Reduce output to `stdout`](#cypress-run-quiet) |
| `--record` | [Whether to record the test run](#cypress-run-record-key-lt-record-key-gt) |
@@ -439,6 +440,16 @@ documentation to learn more.
cypress run --port 8080
```
+#### `cypress run --posix-exit-codes` {#cypress-run-posix-exit-codes}
+
+This changes the default behavior of Cypress regarding exit codes. This flag causes Cypress to exit with POSIX exit code of 1 when there are test failures or if Cypress could not run, rather than the number of tests that failed.
+
+```shell
+cypress run --posix-exit-codes
+```
+
+For more about Cypress' exit code behavior, see the [Exit Code section](/app/references/command-line#Exit-code).
+
#### `cypress run --project ` {#cypress-run-project-lt-project-path-gt}
To see this in action we've set up an
@@ -602,7 +613,7 @@ $ echo $?
0
```
-If there are any test failures, then the exit code will match the number of
+By default, if there are any test failures, then the exit code will match the number of
tests that failed.
```text
@@ -617,6 +628,22 @@ $ echo $?
2
```
+You can change this behavior by passing the `--posix-exit-codes` flag. When this flag is passed,
+the exit code will be 0 if all tests pass. If there are any test failures or if Cypress could not run,
+the exit code will be 1.
+
+```text
+## Spec with two failing tests
+$ cypress run
+...
+ Tests Passing Failing
+ ✖ 1 of 1 failed (100%) 00:22 17 14 2
+
+## print exit code on Mac or Linux
+$ echo $?
+1
+```
+
If Cypress could not run for some reason (for example if no spec files were
found) then the exit code will be 1.
@@ -975,6 +1002,7 @@ and with Windows CMD and PowerShell terminal windows.
| Version | Changes |
| ------------------------------------------ | ---------------------------------------------------------- |
+| [15.4.0](/app/references/changelog#15-4-0) | Added `--posix-exit-codes` flag to `cypress run` |
| [12.6.0](/app/references/changelog#12-6-0) | Added `--auto-cancel-after-failures` flag to `cypress run` |
| [5.4.0](/app/references/changelog) | Added `prune` subcommand to `cypress cache` |
| [5.4.0](/app/references/changelog) | Added `--size` flag to `cypress cache list` subcommand |
diff --git a/docs/app/references/experiments.mdx b/docs/app/references/experiments.mdx
index 1734e01569..1116d7ed14 100644
--- a/docs/app/references/experiments.mdx
+++ b/docs/app/references/experiments.mdx
@@ -263,11 +263,10 @@ creating `e2e` and `component` objects inside your Cypress configuration.
These experiments are available to be specified inside the `e2e` configuration
object:
-| Option | Default | Description |
-| -------------------------------- | ------- | --------------------------------------------------------------------------------------------------------- |
-| `experimentalStudio` | `false` | Generate and save commands directly to your test suite by interacting with your app as an end user would. |
-| `experimentalRunAllSpecs` | `false` | Enables the "Run All Specs" UI feature, allowing the execution of multiple specs sequentially. |
-| `experimentalOriginDependencies` | `false` | Enables support for `Cypress.require` within `cy.origin`. |
+| Option | Default | Description |
+| -------------------------------- | ------- | ---------------------------------------------------------------------------------------------- |
+| `experimentalRunAllSpecs` | `false` | Enables the "Run All Specs" UI feature, allowing the execution of multiple specs sequentially. |
+| `experimentalOriginDependencies` | `false` | Enables support for `Cypress.require` within `cy.origin`. |
### Component Testing
@@ -282,6 +281,7 @@ configuration object:
| Version | Changes |
| -------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
+| [15.4.0](/app/references/changelog) | Removed `experimentalStudio`. Cypress Studio is available as default behavior. |
| [14.0.0](/app/references/changelog#14-0-0) | Removed `experimentalJustInTimeCompile` and `experimentalSkipDomainInjection` and made it default behavior. |
| [13.14.0](/app/references/changelog#13-14-0) | Added support for configuring the Experimental Just-In-Time (JIT) Compiling for component testing via `experimentalJustInTimeCompile`. |
| [13.4.0](/app/references/changelog#13-4-0) | Added support for configuring the Experimental Flake Detection strategy via `retries.experimentalStrategy` and `retries.experimentalOptions`. |
diff --git a/docs/app/references/module-api.mdx b/docs/app/references/module-api.mdx
index ee997bb427..57a96470fe 100644
--- a/docs/app/references/module-api.mdx
+++ b/docs/app/references/module-api.mdx
@@ -77,6 +77,7 @@ Just like the [Command Line options](/app/references/command-line) for
| `exit` | _boolean_ | Whether to close Cypress after all tests run |
| `parallel` | _boolean_ | Run recorded specs in [parallel](/cloud/features/smart-orchestration/parallelization) across multiple machines |
| `port` | _number_ | Override default port |
+| `posixExitCodes` | _boolean_ | Exit with a POSIX-compliant exit code rather than the number of failed tests. |
| `project` | _string_ | Path to a specific project |
| `quiet` | _boolean_ | If passed, Cypress output will not be printed to `stdout`. Only output from the configured [Mocha reporter](/app/tooling/reporters) will print. |
| `record` | _boolean_ | Whether to record the test run |
@@ -367,6 +368,7 @@ node ./wrapper cypress run --browser chrome --config ...
| Version | Changes |
| ------------------------------------------ | ------------------------------------------------------- |
+| [15.4.0](/app/references/changelog#15-4-0) | Added `posixExitCodes` to run options. |
| [12.6.0](/app/references/changelog#12-6-0) | Added `autoCancelAfterFailures` to run options. |
| [10.0.0](/app/references/changelog#10-0-0) | `slowTestThreshold` is now scoped to each testing type. |
| [8.7.0](/app/references/changelog#8-7-0) | Added `slowTestThreshold` configuration option. |
diff --git a/src/components/docs-image/style.module.css b/src/components/docs-image/style.module.css
index 079cc46de8..26b3655489 100644
--- a/src/components/docs-image/style.module.css
+++ b/src/components/docs-image/style.module.css
@@ -1,10 +1,10 @@
.docsImage {
- margin-bottom: 1rem;
+ margin-bottom: 2rem;
box-shadow: 0 2px 10px 1px rgba(0, 0, 0, 0.26);
}
.noBorder {
- margin-bottom: 1rem;
+ margin-bottom: 2rem;
box-shadow: none;
}
diff --git a/src/components/video-local/style.module.css b/src/components/video-local/style.module.css
index 12d2ba662e..422fd94323 100644
--- a/src/components/video-local/style.module.css
+++ b/src/components/video-local/style.module.css
@@ -1,5 +1,5 @@
.docsVideo {
- margin-bottom: 1.4rem;
+ margin-bottom: 2rem;
}
.docsVideo video {
diff --git a/src/css/custom.scss b/src/css/custom.scss
index 4d7e524909..92b84e82eb 100644
--- a/src/css/custom.scss
+++ b/src/css/custom.scss
@@ -122,7 +122,6 @@
--ifm-heading-font-family: Poppins;
--ifm-heading-font-weight: var(--ifm-font-weight-bold);
--ifm-line-height-base: 1.6;
- --ifm-heading-color: theme(colors.gray.1000) --ifm-code-font-size: 95%;
--ifm-pre-line-height: 1.5em;
--ifm-code-background-color: #282a36;
@@ -293,6 +292,18 @@ html[data-theme='dark'] {
}
}
+.alert.alert--secondary {
+ background-color: var(--ifm-color-indigo-50);
+ color: var(--ifm-color-indigo-1000);
+ --ifm-alert-border-color: var(--ifm-color-indigo-400);
+
+ [data-theme='dark'] & {
+ background-color: var(--ifm-color-indigo-1000);
+ color: var(--ifm-color-indigo-50);
+ --ifm-alert-border-color: var(--ifm-color-indigo-800);
+ }
+}
+
div[class^='announcementBar'] {
font-size: 1rem;
font-weight: var(--ifm-font-weight-semibold);
diff --git a/src/css/embeds.scss b/src/css/embeds.scss
index 8b018768cd..398110b6ce 100644
--- a/src/css/embeds.scss
+++ b/src/css/embeds.scss
@@ -6,7 +6,7 @@
overflow: hidden;
max-width: 100%;
height: auto;
- margin-bottom: 1rem;
+ margin-bottom: 2rem;
box-shadow: 0 0 3px rgb(0 0 0 / 30%);
border: 1px solid var(--ifm-toc-border-color);
}
diff --git a/src/css/markdown.scss b/src/css/markdown.scss
index 0ee669f181..8ba074a7ac 100644
--- a/src/css/markdown.scss
+++ b/src/css/markdown.scss
@@ -73,7 +73,7 @@ div.markdown {
&.border-indigo-500 {
html[data-theme='dark'] & {
color: var(--ifm-color-jade-100);
- border-color:var(--ifm-color-jade-100);
+ border-color: var(--ifm-color-jade-100);
}
}
@@ -102,6 +102,10 @@ div.markdown {
}
}
+ .alert {
+ margin-bottom: 2rem;
+ }
+
.alert,
& {
// add border bottom to code tags that are in a link
diff --git a/src/css/table-of-contents.scss b/src/css/table-of-contents.scss
index 486e6dc858..4fa98ec132 100644
--- a/src/css/table-of-contents.scss
+++ b/src/css/table-of-contents.scss
@@ -32,10 +32,11 @@
.table-of-contents .table-of-contents__link--active {
@apply text-indigo-500;
+ font-weight: 700;
+
html[data-theme='dark'] & {
@apply text-indigo-300;
}
- font-weight: 700;
}
.table-of-contents__left-border {
diff --git a/static/img/api/prompt/cy-prompt-demo.mp4 b/static/img/api/prompt/cy-prompt-demo.mp4
new file mode 100644
index 0000000000..21de66eb21
Binary files /dev/null and b/static/img/api/prompt/cy-prompt-demo.mp4 differ
diff --git a/static/img/api/prompt/cy-prompt-need-more-info.mp4 b/static/img/api/prompt/cy-prompt-need-more-info.mp4
new file mode 100644
index 0000000000..11db1c3de1
Binary files /dev/null and b/static/img/api/prompt/cy-prompt-need-more-info.mp4 differ
diff --git a/static/img/api/prompt/gherkin-example-cy-prompt-command-log.png b/static/img/api/prompt/gherkin-example-cy-prompt-command-log.png
new file mode 100644
index 0000000000..cdfef8fac4
Binary files /dev/null and b/static/img/api/prompt/gherkin-example-cy-prompt-command-log.png differ