JavaScript · Cypress
Food delivery with Cypress
Filter restaurants, add dishes with quantity steppers, customise a pizza in a modal, handle a replace-cart prompt, add tip and coupon, then watch the order move live and rate it.
App under test
🍔 FoodDash
- URL
- /apps/food
- Login
- not required
- Coupon
- FEAST50 (min ₹299)
- Free delivery
- above ₹499
Scenarios to automate
Work top to bottom — each one adds a new technique.
- 1
Filters & switch
BeginnerCombine cuisine-* chips, veg-only (role=switch), food-search and restaurant-sort; assert restaurant-count.
- 2
ADD becomes a stepper
Beginneradd-<item> turns into <item>-dec / <item>-qty / <item>-inc; decreasing to 0 brings ADD back.
- 3
Customisation modal
IntermediatePick size-* and topping-* (max 3 — the 4th is disabled); custom-total updates live.
- 4
Replace cart prompt
IntermediateAdding from a second restaurant opens replace-cart-modal; keep-cart vs confirm-replace.
- 5
Coupon rules
IntermediateFEAST50 under ₹299 shows how much more to add; above it caps the discount at ₹100.
- 6
Bill maths
AdvancedVerify bill-items, bill-discount, bill-delivery (free ≥ ₹499), bill-taxes (5%) and bill-total with a tip.
- 7
Live tracking
Advancedorder-status moves Order placed → Preparing → Out for delivery → Delivered every ~3s.
- 8
Rate & reorder
IntermediateAfter delivery, rate-* + submit-rating shows rating-thanks; reorder-<id> refills the cart.
Sample Cypress suite
A working starting point that finds elements every way Cypress can — by role, label, text, id, name, CSS, XPath and data-testid — so you practice them all. Pick your language, switch to data-testid only to compare, or try your own in the Locator Playground.
Cypress runs inside the browser, so it only supports JavaScript and TypeScript — there is no Python, Java or C# version of Cypress. For those languages, see Selenium or Playwright.
// Uses the getByTestId custom command from the Cypress setup (cypress/support/commands.js).
// Locators in this suite: cy.contains ×2 · #id ×1 · [name] ×1 · [aria-label] ×1 · getByTestId ×21
describe('FoodDash — food delivery', () => {
it('orders a customised pizza and tracks it', () => {
cy.visit('/apps/food');
cy.contains('button', 'Pizza').click();
cy.getByTestId('restaurant-count').should('contain', '1 restaurant');
cy.getByTestId('open-restaurant-r3').click();
cy.getByTestId('restaurant-title').should('contain', 'Slice of Napoli');
// Customise a Margherita: medium + olives
cy.getByTestId('add-r3i1').click();
cy.getByTestId('size-medium').click();
cy.getByTestId('topping-olives').check();
cy.getByTestId('custom-total').should('contain', '₹489');
cy.getByTestId('add-customized').click();
cy.getByTestId('add-r3i4').click();
cy.get('[aria-label="Add one Garlic Bread"]').click();
cy.getByTestId('r3i4-qty').should('contain', '2');
cy.getByTestId('cart-count').should('contain', '3');
cy.getByTestId('view-cart').click();
cy.location('pathname').should('include', '/apps/food/checkout');
cy.get('#promo-code').type('FEAST50');
cy.contains('button', 'Apply').click();
cy.getByTestId('promo-message').should('contain', 'applied');
cy.getByTestId('tip-20').click();
cy.getByTestId('bill-delivery').should('contain', 'FREE');
cy.getByTestId('bill-total').should('contain', '₹741');
cy.getByTestId('address-home').click();
cy.get('[name="delivery-phone"]').type('9876543210');
cy.getByTestId('pay-upi').click();
cy.getByTestId('place-order').click();
cy.getByTestId('order-placed').should('be.visible');
// The status advances on its own — wait for text, never sleep
cy.getByTestId('order-status').should('contain', 'Preparing');
});
});