JavaScript · Cypress
Help desk with Cypress
Customers raise tickets (priority set by category); agents work a queue with live SLA countdowns and breach states, bulk-assign, reply with canned responses and formatting, add internal notes, and resolve with a required reason.
App under test
🎧 DeskFlow
- URL
- /apps/helpdesk
- Agent
- agent@deskflow.dev
- Password
- Desk@123
- SLA
- Urgent 30m · High 1h · Med 4h · Low 24h
Scenarios to automate
Work top to bottom — each one adds a new technique.
- 1
Derived priority
BeginnerChoosing ticket-category shows which priority the ticket will get (Technical → High).
- 2
Live SLA timers
Intermediatesla-<id> counts down each second; breached tickets have data-breached="true" and red text.
- 3
Queue filters
Beginnerstatus-filter, priority-filter, owner-filter and queue-search combine; assert queue-count.
- 4
Bulk assign
Intermediateselect-all-tickets → bulk-assign-me updates every assignee-<id> cell.
- 5
Toolbar formatting
IntermediateSelect text in reply-text, click format-bold; the sent message renders <strong>.
- 6
Internal notes
Intermediateinternal-note switch → message has data-internal="true" and doesn't count as a first response.
- 7
First response
AdvancedSending a public reply stops the SLA timer (“Responded”) and moves Open → Pending.
- 8
Resolution rule
IntermediateSetting ticket-status to Resolved without resolution-category shows ticket-error.
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 ×5 · #id ×4 · [name] ×3 · [aria-label] ×3 · getByTestId ×10
describe('DeskFlow — help desk', () => {
it('raises a ticket and resolves it as an agent', () => {
cy.visit('/apps/helpdesk');
cy.get('#requester-name').type('Grace Lee');
cy.get('[name="requester-email"]').type('grace@globex.com');
cy.getByTestId('ticket-category').select('technical');
cy.get('#ticket-subject').type('Cannot export report to PDF');
cy.getByTestId('ticket-description').type('The export button spins forever and nothing downloads.');
cy.contains('button', 'Submit ticket').click();
cy.getByTestId('ticket-created').should('contain', '#1041');
// Switch to the agent side
cy.getByTestId('agent-login-link').click();
cy.get('[name="agent-email"]').type('agent@deskflow.dev');
cy.get('#agent-password').type('Desk@123');
cy.contains('button', 'Sign in').click();
cy.location('pathname').should('include', '/apps/helpdesk/queue');
cy.getByTestId('open-ticket').eq(0).should('contain', 'Cannot export report');
cy.getByTestId('sla-1041').should('contain', '00:5');
cy.getByTestId('open-ticket').eq(0).click();
cy.contains('button', 'Assign to me').click();
cy.getByTestId('ticket-toast').should('contain', 'Assigned');
cy.get('[aria-label="Insert canned response"]').select('greeting');
cy.getByTestId('send-reply').click();
cy.getByTestId('message').eq(1).should('contain', 'thanks for reaching out');
cy.get('[aria-label="Internal note"]').click();
cy.get('[aria-label="Reply"]').type('Reproduced on staging, escalating to dev.');
cy.getByTestId('send-reply').click();
cy.getByTestId('message').eq(2).should('contain', 'Reproduced on staging');
cy.get('[name="ticket-status"]').select('Resolved');
cy.contains('button', 'Update ticket').click();
cy.getByTestId('ticket-error').should('be.visible');
cy.get('#resolution-category').select('bug-fixed');
cy.contains('button', 'Update ticket').click();
cy.getByTestId('ticket-status-badge').should('contain', 'Resolved');
});
});