PracticeQAAutomation logoPracticeQAAutomation
Cy

JavaScript · Cypress

CRM with Cypress

A leads table with filters, select-all and bulk assign, a new-lead modal with duplicate checks, an activity log, convert-to-deal, and a Kanban pipeline you can drag cards across.

App under test

📈 SalesPulse

URL
/apps/crm
Email
sales@crm.dev
Password
Crm@123
Stages
Qualified → Won/Lost

Scenarios to automate

Work top to bottom — each one adds a new technique.

  1. 1

    Table filters

    Beginner

    Combine lead-search, lead-status-filter and lead-source-filter; assert lead-count and rows.

  2. 2

    Select all & bulk assign

    Intermediate

    select-all-leads ticks every visible row; bulk-owner + apply-bulk updates owner-<id> cells.

  3. 3

    New lead validation

    Intermediate

    save-lead with an existing email shows “already exists”; bad phone/value show error-*.

  4. 4

    Activity log

    Intermediate

    Switch activity-note/call/email, save, and assert the newest activity-item text.

  5. 5

    Convert to deal

    Advanced

    convert-lead → deal-value + deal-close → lead-status becomes Converted and converted-banner appears.

  6. 6

    Kanban via menu

    Intermediate

    Change move-deal-<company> and verify the card is inside stage-<id> and stage-total-* updates.

  7. 7

    Kanban drag & drop

    Advanced

    Drag a deal-card onto another stage-* column (HTML5 DnD — dispatch events in Selenium/Cypress).

  8. 8

    Dashboard KPIs

    Beginner

    Winning a deal changes kpi-won and kpi-win-rate on the dashboard.

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.

Language

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.

salespulse.cy.js
// Uses the getByTestId custom command from the Cypress setup (cypress/support/commands.js).
// Locators in this suite: cy.contains ×6 · #id ×5 · [name] ×4 · [aria-label] ×4 · getByTestId ×10
describe('SalesPulse — CRM', () => {
  it('adds a lead and moves the deal through the pipeline', () => {
    cy.visit('/apps/crm');
    cy.get('#crm-email').type('sales@crm.dev');
    cy.get('[name="crm-password"]').type('Crm@123');
    cy.contains('button', 'Sign in').click();
    cy.location('pathname').should('include', '/apps/crm/dashboard');
    cy.getByTestId('nav-leads').click();
    cy.getByTestId('new-lead').click();
    cy.get('#lead-name').type('Grace Lee');
    cy.get('[name="lead-company"]').type('Globex Corp');
    cy.get('#lead-email').type('grace@globex.com');
    cy.get('[name="lead-phone"]').type('5550142233');
    cy.getByTestId('lead-source').select('linkedin');
    cy.get('#lead-value').type('45000');
    cy.contains('button', 'Save lead').click();
    cy.getByTestId('leads-toast').should('contain', 'created');
    cy.getByTestId('leads-table').should('contain', 'Globex Corp');

    // Newest lead is listed first
    cy.getByTestId('open-lead').eq(0).click();
    cy.getByTestId('lead-title').should('contain', 'Grace Lee');
    cy.contains('button', 'Log call').click();
    cy.get('[aria-label="Activity details"]').type('Intro call — interested in the annual plan');
    cy.contains('button', 'Save call').click();
    cy.getByTestId('activity-timeline').should('contain', 'annual plan');
    cy.contains('button', 'Convert to deal').click();
    cy.get('[name="deal-value"]').type('45000');
    cy.get('#deal-close').select('30');
    cy.contains('button', 'Create deal').click();
    cy.getByTestId('lead-status').should('contain', 'Converted');
    cy.getByTestId('view-pipeline').click();
    cy.get('[aria-label="Qualified"]').should('contain', 'Globex Corp');
    cy.get('[aria-label="Move Globex Corp"]').select('proposal');
    cy.get('[aria-label="Proposal"]').should('contain', 'Globex Corp');
    cy.getByTestId('stage-total-proposal').should('contain', '$212,000');
  });
});

Practicing another tool?