diff --git a/.circleci/cache-version.txt b/.circleci/cache-version.txt
index f23f4f6ae2..46785a31bf 100644
--- a/.circleci/cache-version.txt
+++ b/.circleci/cache-version.txt
@@ -1,2 +1,2 @@
# Bump this version to force CI to re-create the cache from scratch.
-10-2-2025
+10-3-2025
diff --git a/.circleci/src/pipeline/@pipeline.yml b/.circleci/src/pipeline/@pipeline.yml
index 17f4547441..94f58f9c05 100644
--- a/.circleci/src/pipeline/@pipeline.yml
+++ b/.circleci/src/pipeline/@pipeline.yml
@@ -118,7 +118,7 @@ commands:
name: Set environment variable to determine whether or not to persist artifacts
command: |
echo "Setting SHOULD_PERSIST_ARTIFACTS variable"
- echo 'if ! [[ "$CIRCLE_BRANCH" != "develop" && "$CIRCLE_BRANCH" != "release/"* && "$CIRCLE_BRANCH" != "electron-37" ]]; then
+ echo 'if ! [[ "$CIRCLE_BRANCH" != "develop" && "$CIRCLE_BRANCH" != "release/"* && "$CIRCLE_BRANCH" != "feat/cy-prompt" ]]; then
export SHOULD_PERSIST_ARTIFACTS=true
fi' >> "$BASH_ENV"
# You must run `setup_should_persist_artifacts` command and be using bash before running this command
diff --git a/.circleci/src/pipeline/workflows/@main.yml b/.circleci/src/pipeline/workflows/@main.yml
index ed3dc7d9d1..a16e1189a9 100644
--- a/.circleci/src/pipeline/workflows/@main.yml
+++ b/.circleci/src/pipeline/workflows/@main.yml
@@ -5,7 +5,7 @@ linux-x64:
- equal: [ develop, << pipeline.git.branch >> ]
# use the following branch as well to ensure that v8 snapshot cache updates are fully tested
- equal: [ 'update-v8-snapshot-cache-on-develop', << pipeline.git.branch >> ]
- - equal: [ 'electron-37', << pipeline.git.branch >> ]
+ - equal: [ 'feat/cy-prompt', << pipeline.git.branch >> ]
- matches:
pattern: /^release\/\d+\.\d+\.\d+$/
value: << pipeline.git.branch >>
@@ -309,7 +309,7 @@ linux-x64:
- /^release\/\d+\.\d+\.\d+$/
# use the following branch as well to ensure that v8 snapshot cache updates are fully tested
- 'update-v8-snapshot-cache-on-develop'
- - 'chore/refactor_cli_to_ts'
+ - 'feat/cy-prompt'
context: test-runner:npm-release
requires:
- ready-to-release
diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md
index f008db8dcf..83ac1ec094 100644
--- a/cli/CHANGELOG.md
+++ b/cli/CHANGELOG.md
@@ -7,6 +7,7 @@ _Released 10/7/2025 (PENDING)_
- 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).
- 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` 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:**
diff --git a/cli/types/cypress.d.ts b/cli/types/cypress.d.ts
index 15f4fa668f..84b0701d77 100644
--- a/cli/types/cypress.d.ts
+++ b/cli/types/cypress.d.ts
@@ -1,4 +1,3 @@
-/* eslint-disable @typescript-eslint/no-unused-vars */
///
///
///
@@ -59,6 +58,9 @@ declare namespace Cypress {
interface ObjectLike {
[key: string]: any
}
+ interface PromptOptions {
+ excludeFromAI?: Record
+ }
interface Auth {
username: string
password: string
@@ -684,22 +686,22 @@ declare namespace Cypress {
Keyboard: {
defaults(options: Partial): void
Keys: {
- DOWN: 'ArrowDown',
- LEFT: 'ArrowLeft',
- RIGHT: 'ArrowRight',
- UP: 'ArrowUp',
- END: 'End',
- HOME: 'Home',
- PAGEDOWN: 'PageDown',
- PAGEUP: 'PageUp',
- ENTER: 'Enter',
- TAB: 'Tab',
- BACKSPACE: 'Backspace',
- SPACE: 'Space',
- DELETE: 'Delete',
- INSERT: 'Insert',
- ESC: 'Escape',
- },
+ DOWN: 'ArrowDown'
+ LEFT: 'ArrowLeft'
+ RIGHT: 'ArrowRight'
+ UP: 'ArrowUp'
+ END: 'End'
+ HOME: 'Home'
+ PAGEDOWN: 'PageDown'
+ PAGEUP: 'PageUp'
+ ENTER: 'Enter'
+ TAB: 'Tab'
+ BACKSPACE: 'Backspace'
+ SPACE: 'Space'
+ DELETE: 'Delete'
+ INSERT: 'Insert'
+ ESC: 'Escape'
+ }
}
/**
@@ -755,7 +757,7 @@ declare namespace Cypress {
* Trigger action
* @private
*/
- action: (action: string, ...args: any[]) => T
+ action: (action: string, ...args: any[]) => T
/**
* Load files
@@ -1849,7 +1851,12 @@ declare namespace Cypress {
* @see https://on.cypress.io/prevuntil
*/
prevUntil(element: E | JQuery, filter?: string, options?: Partial): Chainable>
-
+ /**
+ * An AI-powered command that generates Cypress commands from natural language test steps.
+ *
+ * @see https://on.cypress.io/prompt
+ */
+ prompt(steps: string[], options?: PromptOptions): Chainable
/**
* Read a file and yield its contents.
*
@@ -2898,8 +2905,8 @@ declare namespace Cypress {
}
type RetryStrategyWithModeSpecs = RetryStrategy & {
- openMode: boolean; // defaults to false
- runMode: boolean; // defaults to true
+ openMode: boolean // defaults to false
+ runMode: boolean // defaults to true
}
type RetryStrategy =
@@ -2907,18 +2914,18 @@ declare namespace Cypress {
| RetryStrategyDetectFlakeButAlwaysFailType
interface RetryStrategyDetectFlakeAndPassOnThresholdType {
- experimentalStrategy: "detect-flake-and-pass-on-threshold"
+ experimentalStrategy: 'detect-flake-and-pass-on-threshold'
experimentalOptions?: {
- maxRetries: number; // defaults to 2 if experimentalOptions is not provided, must be a whole number > 0
- passesRequired: number; // defaults to 2 if experimentalOptions is not provided, must be a whole number > 0 and <= maxRetries
+ maxRetries: number // defaults to 2 if experimentalOptions is not provided, must be a whole number > 0
+ passesRequired: number // defaults to 2 if experimentalOptions is not provided, must be a whole number > 0 and <= maxRetries
}
}
interface RetryStrategyDetectFlakeButAlwaysFailType {
- experimentalStrategy: "detect-flake-but-always-fail"
+ experimentalStrategy: 'detect-flake-but-always-fail'
experimentalOptions?: {
- maxRetries: number; // defaults to 2 if experimentalOptions is not provided, must be a whole number > 0
- stopIfAnyPassed: boolean; // defaults to false if experimentalOptions is not provided
+ maxRetries: number // defaults to 2 if experimentalOptions is not provided, must be a whole number > 0
+ stopIfAnyPassed: boolean // defaults to false if experimentalOptions is not provided
}
}
interface ResolvedConfigOptions {
@@ -3140,7 +3147,7 @@ declare namespace Cypress {
* @see https://on.cypress.io/experiments#Experimental-CSP-Allow-List
* @default false
*/
- experimentalCspAllowList: boolean | experimentalCspAllowedDirectives[],
+ experimentalCspAllowList: boolean | experimentalCspAllowedDirectives[]
/**
* Allows listening to the `before:run`, `after:run`, `before:spec`, and `after:spec` events in the plugins file during interactive mode.
* @default false
@@ -3272,6 +3279,11 @@ declare namespace Cypress {
* @default false
*/
experimentalOriginDependencies?: boolean
+ /**
+ * Enables support for `cy.prompt`, an AI-powered command that turns natural language steps into executable Cypress test code.
+ * @default false
+ */
+ experimentalPromptCommand?: boolean
}
/**
diff --git a/guides/cy-prompt-development.md b/guides/cy-prompt-development.md
new file mode 100644
index 0000000000..b4c485edde
--- /dev/null
+++ b/guides/cy-prompt-development.md
@@ -0,0 +1,52 @@
+# `cy.prompt` Development
+
+In production, the code used to facilitate the prompt command will be retrieved from the Cloud.
+
+To run against locally developed `cy.prompt`:
+
+- Clone the `cypress-services` repo
+ - Run `yarn && yarn all`
+ - Run `yarn watch` in `app/packages/cy-prompt`
+- Set:
+ - `CYPRESS_INTERNAL_ENV=` (e.g. `staging` or `production` if you want to hit those deployments of `cypress-services` or `development` if you want to hit a locally running version of `cypress-services`)
+ - `CYPRESS_LOCAL_CY_PROMPT_PATH` to the path to the `cypress-services/app/packages/cy-prompt/dist/development` directory
+
+To run against a deployed version of `cy.prompt`:
+
+- Set:
+ - `CYPRESS_INTERNAL_ENV=` (e.g. `staging` or `production` if you want to hit those deployments of `cypress-services` or `development` if you want to hit a locally running version of `cypress-services`)
+
+Regardless of running against local or deployed `cy.prompt`:
+
+- Clone the `cypress` repo
+ - Run `yarn`
+ - Run `yarn cypress:open`
+ - Log In to the Cloud via the App
+ - Open a project that has `experimentalPromptCommand: true` set in the config of the `cypress.config.js|ts` file within `e2e`. Ensure the project has the feature flag `cy-prompt` enabled.
+
+To run against a deployed version of `cy.prompt`:
+
+- Set:
+ - `CYPRESS_INTERNAL_ENV=` (e.g. `staging` or `production` if you want to hit those deployments of `cypress-services` or `development` if you want to hit a locally running version of `cypress-services`)
+
+## Types
+
+The prompt bundle provides the types for the `app`, `driver`, and `server` interfaces that are used within the Cypress code. To incorporate the types into the code base, run:
+
+```sh
+yarn gulp downloadPromptTypes
+```
+
+or to reference a local `cypress_services` repo:
+
+```sh
+CYPRESS_LOCAL_CY_PROMPT_PATH= yarn gulp downloadPromptTypes
+```
+
+## Testing
+
+### Unit/Component Testing
+
+The code that supports cloud `cy.prompt` and lives in the `cypress` monorepo is unit, integration, and e2e tested in a similar fashion to the rest of the code in the repo. See the [contributing guide](https://github.com/cypress-io/cypress/blob/ad353fcc0f7fdc51b8e624a2a1ef4e76ef9400a0/CONTRIBUTING.md?plain=1#L366) for more specifics.
+
+The code that supports cloud `cy.prompt` and lives in the `cypress-services` monorepo has unit tests that live alongside the code in that monorepo.
diff --git a/packages/app/cypress/e2e/runner/event-manager.cy.ts b/packages/app/cypress/e2e/runner/event-manager.cy.ts
index ad78320cac..a99c5d5907 100644
--- a/packages/app/cypress/e2e/runner/event-manager.cy.ts
+++ b/packages/app/cypress/e2e/runner/event-manager.cy.ts
@@ -50,4 +50,21 @@ describe('event-manager', () => {
cy.wrap(() => eventManager.reporterBus.listeners('runner:next').length).invoke('call').should('equal', 1)
})
})
+
+ it('should reset the prompt store', () => {
+ loadSpec({
+ filePath: 'hooks/basic.cy.js',
+ passCount: 2,
+ })
+
+ cy.window().then((win) => {
+ const eventManager = win.getEventManager()
+
+ cy.spy(eventManager['promptStore'], 'resetState').as('resetState')
+ })
+
+ cy.visitApp(`specs`)
+
+ cy.get('@resetState').should('have.been.calledOnce')
+ })
})
diff --git a/packages/app/src/prompt/PromptErrorMessage.vue b/packages/app/src/prompt/PromptErrorMessage.vue
new file mode 100644
index 0000000000..d8428dc84c
--- /dev/null
+++ b/packages/app/src/prompt/PromptErrorMessage.vue
@@ -0,0 +1,55 @@
+
+
+
+
+ cy.prompt
+
+ Get code
+
+
+
+
+
+
+ Something went wrong
+
+ There was a problem with loading the prompt code. Our team has been
+ notified. If the problem persists, please try again later.
+
+