Recipe
Cypress Patterns
Reusable selectors, commands, and test architecture for Meridian's E2E suite.
data-cy Selectors
Every interactive element carries a data-cy attribute. Never couple tests to CSS classes or text content.
cy.get('[data-cy=license-key-input]').type('XXXX-YYYY-ZZZZ')
cy.get('[data-cy=activate-button]').click()
cy.get('[data-cy=activation-success-toast]')
.should('be.visible')Custom Commands
Wrap repeated flows in commands.ts. Login, license activation, and session seeding are one-liners in specs.
Cypress.Commands.add('login', (email, pw) => {
cy.session([email, pw], () => {
cy.visit('/login')
cy.get('[data-cy=email-input]').type(email)
cy.get('[data-cy=password-input]').type(pw)
cy.get('[data-cy=submit-button]').click()
cy.url().should('include', '/dashboard')
})
})Network Stubs
Intercept KeyAuth and Upstash calls so tests never hit live infrastructure. Fixtures live in cypress/fixtures/.
cy.intercept('POST', '**/api/1.2/activate', {
statusCode: 200,
fixture: 'activation-success.json'
}).as('activate')
cy.wait('@activate')Base URL & Env
Set baseUrl in config and use CYPRESS_ env vars for secrets. Never hardcode credentials.
Full E2E pipeline runs on every PR via GitHub Actions. See CI/CD guide for workflow details.