PAPracticeAutomation
Cy

JavaScript Β· Cypress

E-commerce with Cypress

Automate a full shopping journey β€” login, catalogue, cart, coupons, checkout and order history.

App under test

Nova Shop

URL
/shop
User
demo_user
Password
Demo@123
Coupons
SAVE10 Β· FLAT20
Declined card
4000 0000 0000 0002
Launch Nova Shop β†’

Scenarios to automate

Work top to bottom β€” each one adds a new technique.

  1. 1

    Valid & invalid login

    Beginner

    demo_user / Demo@123 succeeds; wrong password and empty fields show login-error.

  2. 2

    Locked-out user

    Beginner

    locked_user gets β€œSorry, this user has been locked out.”

  3. 3

    Slow login

    Intermediate

    slow_user takes ~3s β€” wait for the URL or product grid, never sleep.

  4. 4

    Route guard

    Beginner

    Visiting /shop/cart signed out redirects to /shop.

  5. 5

    Search, filter & sort

    Intermediate

    Assert product-count text, no-results state, and that product-price values are sorted.

  6. 6

    Cart badge & quantities

    Intermediate

    Add/remove from the grid, change qty in the cart, check line-total and totals maths.

  7. 7

    Coupons

    Intermediate

    SAVE10 = 10% off, FLAT20 = $20 off above $100, anything else is rejected.

  8. 8

    Checkout validation

    Intermediate

    Submit empty to collect error-* messages; fix them one by one.

  9. 9

    Declined card

    Advanced

    4000 0000 0000 0002 shows payment-error; switch to Cash on delivery and succeed.

  10. 10

    Order history

    Advanced

    Order id on the success page must appear in orders-table after navigation.

Sample Cypress suite

A working starting point written against this app's real data-testids.

shop.cy.js
describe('Nova Shop', () => {
  beforeEach(() => {
    cy.visit('/shop');
    cy.getByTestId('username').type('demo_user');
    cy.getByTestId('password').type('Demo@123');
    cy.getByTestId('login-button').click();
    cy.location('pathname').should('eq', '/shop/products');
  });

  it('buys headphones with a coupon', () => {
    cy.getByTestId('search-input').type('headphones');
    cy.getByTestId('product-card').should('have.length', 1);
    cy.getByTestId('add-to-cart-p1').click();
    cy.getByTestId('cart-badge').should('have.text', '1');

    cy.getByTestId('cart-link').click();
    cy.getByTestId('coupon-input').type('SAVE10');
    cy.getByTestId('apply-coupon').click();
    cy.getByTestId('discount').should('contain', '$13.00');

    cy.getByTestId('checkout-button').click();
    cy.getByTestId('first-name').type('Ada');
    cy.getByTestId('last-name').type('Lovelace');
    cy.getByTestId('email').type('ada@example.com');
    cy.getByTestId('phone').type('5551234567');
    cy.getByTestId('address').type('1 Analytical Way');
    cy.getByTestId('city').type('Austin');
    cy.getByTestId('state').select('Texas');
    cy.getByTestId('zip').type('73301');
    cy.getByTestId('card-name').type('Ada Lovelace');
    cy.getByTestId('card-number').type('4242424242424242');
    cy.getByTestId('card-expiry').type('1230');
    cy.getByTestId('card-cvv').type('123');
    cy.getByTestId('accept-terms').check();
    cy.getByTestId('place-order').click();

    // Commands retry until the ~2s "processing" finishes.
    cy.getByTestId('order-success').should('be.visible');
    cy.getByTestId('order-id').invoke('text').should('match', /^NS-\d+$/);
  });

  it('sorts by price, low to high', () => {
    cy.getByTestId('sort-select').select('price-asc');
    cy.getByTestId('product-price').then(($prices) => {
      const prices = [...$prices].map((el) => Number(el.innerText.replace('$', '')));
      expect(prices).to.deep.equal([...prices].sort((a, b) => a - b));
    });
  });
});

Practising another tool?