guides/studio-development.md
Studio is delivered from Cypress Cloud. In production, the Studio bundle is retrieved from the Cloud at runtime. For local development, the environment variable CYPRESS_LOCAL_STUDIO_PATH can be used to run against a local Studio build from the cypress-services repo.
To run against locally developed Studio:
cypress-services repo (requires Cypress organization membership)
yarnyarn watch in app/packages/studiocypress-services: run yarn dev in the cypress-services directory firstCYPRESS_INTERNAL_ENV=<environment> (e.g. staging, production, or development for a local cypress-services instance)CYPRESS_LOCAL_STUDIO_PATH: path to cypress-services/app/packages/studio/dist/development (overrides Cloud bundle when set)cypress repo:
yarn and yarn cypress:openstudio-ai feature enabled for that project)Note: With CYPRESS_LOCAL_STUDIO_PATH or when running the app from a local clone, error reporting is bypassed and errors are logged to the browser or Node console. With CYPRESS_LOCAL_STUDIO_PATH, the local Studio code is watched so you can change it without restarting the app.
The studio bundle provides the types for the app and server interfaces that are used within the Cypress code. To incorporate the types into the code base, run:
yarn gulp downloadStudioTypes
or to reference a local cypress_services repo:
CYPRESS_LOCAL_STUDIO_PATH=<path-to-cypress-services/app/studio/dist/development-directory> yarn gulp downloadStudioTypes
The code that supports cloud Studio and lives in the cypress monorepo is unit and component tested in a similar fashion to the rest of the code in the repo. See the contributing guide for more specifics.
The code that supports cloud Studio and lives in the cypress-services monorepo has unit and component tests that live alongside the code in that monorepo.
Helpers for testing Studio with Cypress-in-Cypress live in packages/app/cypress/e2e/studio/helper.ts. The launchStudio helper:
studio fixture project).specName.cy.js).createNewTest parameter).Those tests use the Studio bundle from the Cloud. The studio project uses a canary projectId so it receives the latest Cloud Studio build. For local Studio changes, set process.env.CYPRESS_LOCAL_STUDIO_PATH to your local studio build; Studio is enabled in that environment in packages/frontend-shared/cypress/e2e/e2ePluginSetup.ts.
In order to properly engage with Studio AI, we choose to simulate the cloud interactions that enable it via something like:
cy.mockNodeCloudRequest({
url: '/studio/testgen/n69px6/enabled',
method: 'get',
body: { enabled: true },
})
To ensure that we get the same results from our Studio AI calls every time, we simulate them via something like:
const aiOutput = 'cy.get(\'button\').should(\'have.text\', \'Increment\')'
cy.mockNodeCloudRequest({
url: '/studio/testgen/n69px6/generate',
method: 'post',
body: { recommendations: [{ content: aiOutput }] },
})
The above two helpers actually mock out the Node requests so we still test the interface between the browser and node with these tests.
Also, since protocol does not work properly on the inner Cypress of Cypress in Cypress tests, we choose to create a dummy protocol which means we need to provide a simulated CDP full snapshot that will be sent to AI via something like:
cy.mockStudioFullSnapshot({
id: 1,
nodeType: 1,
nodeName: 'div',
localName: 'div',
nodeValue: 'div',
children: [],
shadowRoots: [],
})