How to Use Studio in Cypress 10.7

Back to Cypress blog

Studio is back in Cypress 10! Studio allows you to generate and save Cypress tests by interaction with your site. Our users love using Studio to:

  • Save the time and monotony of manually writing tests to get to the hard part about test writing faster
  • Rapidly scaffold out test cases based on in-app behaviors
  • Expedite transitioning to Cypress and learning our functionality while creating usable, valuable tests

In this post, I’ll walk you through how to leverage Studio to author tests in Cypress 10.

How To Try Cypress Studio

Cypress Studio is still an experimental feature. Like all Cypress experiments, you can configure Studio in cypress.config:

const { defineConfig } = require('cypress')

module.exports = defineConfig({
  e2e: {
    experimentalStudio: true
  }
})

At the time of this post, Cypress Studio only works with End-to-End Testing. Component Testing may be supported in a future update.

Demo: Creating a Test in Cypress Real World App

Let's see a demo – writing some tests for the Cypress Real World App using Cypress Studio! I followed the instructions, cloned the repository and started up the application.

I've also created a spec, transactions.spec.js, with some basic code to create and log in as a new user.

// Code from Real World App (RWA)
describe('Cypress Studio Demo', () => {
  beforeEach(() => {
    // Seed database with test data
    cy.task('db:seed')

    // Login test user
    cy.database('find', 'users').then((user) => {
      cy.login(user.username, 's3cret', true)
    })
  })

  it('create new transaction', () => {
    // Extend test with Cypress Studio
  })
})

Open Cypress, select transactions.spec.js and go to the runner page. Hover over the test you'd like to author mine is "create new transaction" and click on "Add Commands to Test".

Now the Studio Toolbar appears, and we can start authoring our test.

I followed a common workflow in the Real World App:

  1. Click "$ New"
  2. Search for a user (I typed "Dev" and chose "Devon Becker")
  3. Assert I've found the correct user
  4. Click the user
  5. Enter an amount and a message
  6. Click Submit

Now I've completed my user journey, I can click "Save Commands" and my test will be updated.

The test is now written to transactions.spec.js. The full content is now:

it('create new transaction', () => {
  /* ==== Generated with Cypress Studio ==== */
  cy.get('.MuiButton-label').click();
  cy.get('[data-test="user-list-search-input"]').clear('d');
  cy.get('[data-test="user-list-search-input"]').type('dev');
  cy.get('[data-test="user-list-item-tsHF6_D5oQ"] > .MuiListItemText-root > .MuiListItemText-primary').should('have.text', 'Devon Becker');
  cy.get('[data-test="user-list-item-tsHF6_D5oQ"] > .MuiListItemText-root > .MuiListItemText-primary').click();
  cy.get('#amount').clear();
  cy.get('#amount').type('$50');
  cy.get('#transaction-create-description-input').clear();
  cy.get('#transaction-create-description-input').type('Great job!');
  cy.get('[data-test="transaction-create-submit-payment"]').should('have.text', 'Pay');
  cy.get('[data-test="transaction-create-submit-payment"]').click();
  cy.get('.MuiBox-root-80 > .MuiGrid-container > .MuiGrid-root > .MuiTypography-root').should('have.text', 'Paid $50.00 for Great job!');
  /* ==== End Cypress Studio ==== */
})

The test re-executes to verify everything passes - and so it does.

A Note on Resilient Test Selectors

Let’s take a look at the last few lines of the generated test:

  cy.get('[data-test="transaction-create-submit-payment"]').should('have.text', 'Pay');
  cy.get('[data-test="transaction-create-submit-payment"]').click();
  cy.get('.MuiBox-root-80 > .MuiGrid-container > .MuiGrid-root > .MuiTypography-root').should('have.text', 'Paid $50.00 for Great job!');

The first two commands use data-* selectors - one of our recommended practices for selecting elements. These are less likely to change over time, and ensure your tests are resilient.

The final assertion uses a complex selector based on several classes. This could change with a redesign or even a simple refactor, causing our test to fail, even if it technically still functions from a user point of view.

Cypress will do its best to use attributes less likely to change over time, prioritizing data-* selectors. It uses the same algorithm as the Selector Playground feature - you can see the full algorithm for selector priority in our documentation.

If you do see brittle selectors getting generated, consider adding additional attributes to your application where possible to ensure your test suite remains reliable and maintainable.

Learn More

See our documentation for more information about Cypress Studio, or leave us feedback on Github.