Cypress Commands vs Scenarios - spryker-projects/cypress-boilerplate GitHub Wiki

Overview

This page provides a detailed explanation of the difference and usage of Cypress Commands and Scenarios in the Cypress-Boilerplate project.

  • Cypress commands can be found at: cypress/support/cy-commands/
  • Scenarios can be found at: cypress/support/scenarios/

What are Cypress Commands?

Cypress commands are reusable functions that encapsulate common actions or interactions with the application. They help simplify test scripts by abstracting complex sequences of actions into single, readable commands.

Key Features of Cypress Commands

  • Reusability: Cypress commands enhance reusability by encapsulating actions that can be used across multiple tests.
  • Encapsulation: Commands encapsulate complex actions, making tests easier to write and maintain.
  • Simplified Syntax: Commands provide a simplified syntax for common interactions, improving code readability.

Example:

Cypress.Commands.add(
  'placeOrderViaGlue',
  (
    email: string,
    password: string,
    sku: string,
    shipment: number,
    paymentProvider: string,
    paymentMethod: string,
    offer: string,
    merchant: string
  ): Cypress.Chainable<string> => {
    let token: string
    let cartId: string

    return cy.wrap(null).then(() => {
      return tokenEndpoint
        .getCustomerAccessToken(email, password)
        .then((response) => {
          token = response.body.data.attributes.accessToken
          return token
        })
        .then((token) => {
          return cartEndpoint.createGrossCart(token).then((response) => {
            cartId = response.body.data.id
            return { token, cartId }
          })
        })
        .then(({ token, cartId }) => {
          return itemsEndpoint
            .addOfferToCart(token, cartId, sku, 1, offer, merchant)
            .then(() => {
              return { token, cartId }
            })
        })
        .then(({ token, cartId }) => {
          return checkoutEndpoint
            .placeOrder(
              token,
              cartId,
              email,
              shipment,
              paymentProvider,
              paymentMethod
            )
            .then((response) => {
              return response.body.data.attributes.orderReference
            })
        })
    })
  }
)

For more details, refer to the Cypress Commands documentation.

What are Scenarios?

Scenarios in Cypress refer to the structured and organized representation of repeatable user flows (registration, checkout). They simulate real user interactions and workflows, creating comprehensive and maintainable test suites that reflect real-world usage of the application.

Key Features of Scenarios

  • User-Centric Testing: Focus on how end users interact with the application.
  • Modular Structure: Organize tests into modules or files, each representing specific user stories or functionalities.
  • Reusable Components: Use of reusable commands and functions to streamline the testing process.

Example:

placeOrder = (
    email: string,
    password: string,
    sku: string,
    shipment: number,
    paymentProvider: string,
    paymentMethod: string,
    offer: string,
    merchant: string
  ): Cypress.Chainable<string> => {
    let token: string
    let cartId: string

    return cy.wrap(null).then(() => {
      return tokenEndpoint
        .getCustomerAccessToken(email, password)
        .then((response) => {
          token = response.body.data.attributes.accessToken
          return token
        })
        .then((token) => {
          return cartEndpoint.createGrossCart(token).then((response) => {
            cartId = response.body.data.id
            return { token, cartId }
          })
        })
        .then(({ token, cartId }) => {
          return itemsEndpoint
            .addOfferToCart(token, cartId, sku, 1, offer, merchant)
            .then(() => {
              return { token, cartId }
            })
        })
        .then(({ token, cartId }) => {
          return checkoutEndpoint
            .placeOrder(
              token,
              cartId,
              email,
              shipment,
              paymentProvider,
              paymentMethod
            )
            .then((response) => {
              return response.body.data.attributes.orderReference
            })
        })
    })
  }

Usage Difference

You can find examples of how to use Cypress Commands and Scenarios in the Cypress-Boilerplate project:

Cypress Commands Example

In cypress/e2e/backoffice/backoffice-process-order.cy.ts:

context('Order management', () => {
  before(function () {
    // reset customer addresses
    cy.deleteAllCustomerAddresses(
      customerCredentials.email,
      customerCredentials.password,
      customerCredentials.reference
    )
    // placing an order for processing
    cy.placeOrderViaGlue(
      customerCredentials.email,
      customerCredentials.password,
      productData.availableOffer.concreteSku,
      checkoutData.glueShipment.id,
      checkoutData.gluePayment.providerName,
      checkoutData.gluePayment.methodName,
      productData.availableOffer.offer,
      productData.availableOffer.merchantReference
    ).then((response: string) => {
      orderReference = response
    })
  })
}

Scenarios Example

In cypress/e2e/backoffice/backoffice-process-order-scenario.cy.ts:

import { GlueCheckoutScenarios } from 'cypress/support/scenarios/glue/glue-checkout-scenarios'
import { OmsTransitionScenarios } from '../../support/scenarios/backoffice/oms-transition-scenarios'
import { GlueAddressesScenarios } from '../../support/scenarios/glue/glue-addresses-scenarios'

const glueCheckoutScenarios = new GlueCheckoutScenarios()
const glueAddressesScenarios = new GlueAddressesScenarios()
const omsTransitionScenarios = new OmsTransitionScenarios()

context('Order management', () => {
  before(function () {
    // reset customer addresses
    glueAddressesScenarios.deleteAllCustomerAddresses(
      customerCredentials.email,
      customerCredentials.password,
      customerCredentials.reference
    )
    // placing an order for processing
    glueCheckoutScenarios
      .placeOrder(
        customerCredentials.email,
        customerCredentials.password,
        productData.availableOffer.concreteSku,
        checkoutData.glueShipment.id,
        checkoutData.gluePayment.providerName,
        checkoutData.gluePayment.methodName,
        productData.availableOffer.offer,
        productData.availableOffer.merchantReference
      )
      .then((response: string) => {
        orderReference = response
      })
  })
}

Pros and Cons of Cypress Commands vs. Scenarios

Feature Cypress Commands Cypress Scenarios
Purpose Encapsulate reusable actions Structure end-to-end test cases
Reusability High - Used across multiple tests Moderate - Scenario-specific
Readability High - Abstracts complex actions Moderate - Reflects user workflows
Maintainability High - Update in one place High - Organized by functionality
Setup Complexity Simple to set up Requires logical organization
Execution Speed Fast - Efficient code reuse Moderate - Comprehensive user journeys
Test Granularity Low - Specific actions High - Complete user scenarios
Best Use Case Repeated actions (e.g., login, form submission) Full user flows (e.g., registration, checkout)
Team Collaboration Enhances consistency in common tasks Enhances modular testing and collaboration
Debugging Easier to pinpoint issues in actions Easier to debug user workflows
Developer Experience Moderate - harder to trace and manage since they are globally available and can lack context High - more intuitive and native for developers, as they allow navigating to scenario definitions directly for better context and understanding

Conclusion

Understanding the difference between Cypress Commands and Scenarios can help you decide which approach is more convenient for your project. The main technical difference is that Scenarios must be imported separately into your test files, while commands are called directly from Cypress.

By using Cypress Commands and Scenarios together, you can achieve a well-structured, maintainable, and scalable test suite. These tools provide a powerful approach to efficient and effective testing. Happy testing!

⚠️ **GitHub.com Fallback** ⚠️