On this page10 sections

Cypress — Automate a Checkout Flow

Write a Cypress + TypeScript test suite for a multi-step checkout: add to cart, fill shipping and payment, verify order confirmation, and use cy.intercept() to control the payment API.

Role

Automation QA engineer

Difficulty

Intermediate

Time limit

90–120 min

Category

ui automation

CypressTypeScriptNode.js 18+

Scenario

You are writing E2E tests for the checkout flow of Sauce Demo (https://www.saucedemo.com). The checkout is a 3-step wizard: (1) Cart, (2) Checkout: Your Information, (3) Checkout: Overview → Order Confirmation. Your suite must cover the happy path, a validation failure (missing first name), and an order total assertion. Use cy.intercept() to demonstrate that you can stub the order submission if needed. Custom commands must be used for repetitive setup steps.

Requirements

  • 1.Create a custom command cy.login(username, password) in cypress/support/commands.ts with TypeScript typings
  • 2.Write at least 4 test cases: full checkout success, missing first name validation, order total calculation, and an intercept-based test that stubs the checkout API response
  • 3.Assert the exact confirmation message text on the success page
  • 4.Assert the item total and tax amount on the checkout overview page
  • 5.Use fixture files for test user data and product expectations
  • 6.The suite must pass `npx cypress run` headlessly with zero failing tests
  • 7.TypeScript must be valid: `npx tsc --noEmit` must exit 0

Starter data

  • Target app: https://www.saucedemo.com
  • Login: standard_user / secret_sauce
  • Checkout confirmation message: 'Thank you for your order!'
  • Checkout: Your Information fields: First Name, Last Name, Postal Code
  • Checkout route: /cart.html → /checkout-step-one.html → /checkout-step-two.html → /checkout-complete.html
  • Error selector (for reference): [data-test='error']
  • Item total label: data-test='subtotal-label' (format: 'Item total: $XX.XX')

Expected deliverables

  • A Cypress + TypeScript project runnable with `npm install && npx cypress run`
  • cypress/support/commands.ts with cy.login() and its TypeScript declaration
  • cypress/fixtures/ with at least one fixture file used in tests
  • checkout.cy.ts with at least 4 test cases
  • cypress.config.ts setting baseUrl
  • Output of `npx cypress run` showing all tests passing
  • Output of `npx tsc --noEmit` showing zero errors

Evaluation rubric

DimensionWhat reviewers look for
Custom command qualityIs cy.login() typed correctly in both the implementation and the Cypress.Chainable interface extension? Does it use cy.request() for fast programmatic login or cy.get() for UI login? Is the difference understood and justified?
Intercept usageIs cy.intercept() used to alias and wait for a network request, or to stub a response? Is the alias used with cy.wait('@alias') so the test doesn't rely on arbitrary timing?
Assertion specificityDoes the confirmation test assert the exact message text, not just element visibility? Does the total test parse the dollar amount and compare it to an expected calculated value?
Fixture usageIs test data (user info, expected product prices) loaded from fixture files rather than hardcoded in tests? Are fixtures accessed via cy.fixture() or as static imports?
Test independenceDoes each test start from a known state (logged in, cart cleared)? Is beforeEach used to reset state? Do tests not rely on the side effects of previous tests?
TypeScript correctnessAre Cypress chain types correct? Is the subject type of custom commands specified? Does the project use `/// <reference types='cypress' />` or a `tsconfig.json` with Cypress types included?

Sample solution outline

  • cypress.config.ts: baseUrl: 'https://www.saucedemo.com', specPattern: 'cypress/e2e/**/*.cy.ts'
  • commands.ts: Cypress.Commands.add('login', (username, password) => { cy.visit('/'); cy.get('[data-test=username]').type(username); cy.get('[data-test=password]').type(password); cy.get('[data-test=login-button]').click(); });
  • checkout.cy.ts: beforeEach: cy.login('standard_user', 'secret_sauce'), add Sauce Labs Backpack to cart, visit /cart.html
  • TC-01 Happy path: proceed through checkout steps, submit order, assert cy.url().should('include', 'checkout-complete'), assert cy.contains('Thank you for your order!')
  • TC-02 Missing first name: navigate to /checkout-step-one.html, submit empty first name, assert cy.get('[data-test=error]').should('contain', 'First Name is required')
  • TC-03 Order total: add a product and check /checkout-step-two.html, parse item total and tax from the page, assert they sum to the displayed total
  • TC-04 Intercept: cy.intercept('POST', '**/checkout/complete', { statusCode: 200 }).as('completeOrder'), submit checkout, cy.wait('@completeOrder'), assert confirmation page renders

Common mistakes

  • Typing cy.login() as returning `void` rather than `Cypress.Chainable<void>` — this breaks chaining and the TypeScript declaration
  • Using cy.wait(2000) to wait for page transitions instead of `cy.url().should('include', 'checkout-step-two')` — time-based waits are flaky and hide real latency issues
  • Not clearing the cart between tests — if TC-01 adds an item and TC-02 also adds an item, TC-02 starts with 2 items in the cart, causing the total assertion to fail
  • Intercepting a URL pattern that is too broad and accidentally stubbing unrelated requests
  • Fixture data that duplicates what is already hardcoded in the test — fixtures should be the single source of truth, not a parallel copy
  • Asserting cy.contains('Thank you') instead of the exact message — partial text matches hide future regressions where the message wording changes

Submission checklist

  • package.json, cypress.config.ts, and tsconfig.json are present
  • cy.login() is defined in commands.ts with a TypeScript interface extension
  • At least one fixture file is used in tests
  • checkout.cy.ts has at least 4 independent test cases
  • cy.intercept() is used with cy.wait('@alias') in at least one test
  • All tests pass: `npx cypress run` exits 0
  • No type errors: `npx tsc --noEmit` exits 0
  • README explains install and run steps

Extension ideas

  • +Add a test for the performance_glitch_user: assert that login completes within 5 seconds using cy.clock()
  • +Write a data-driven checkout test using cy.fixture() to iterate over multiple product combinations and verify totals
  • +Add a visual assertion using cypress-image-snapshot on the checkout confirmation page