Cypress Tutorial for Beginners: 7 Steps to Your First Test
A step-by-step Cypress tutorial for beginners — installation, your first test, selectors, assertions, fixtures, custom commands, network stubbing, API tests and headless runs.
Cypress is one of the most popular JavaScript tools for end-to-end web testing, and it shows up regularly in automation job descriptions for product companies and startups in India. This Cypress tutorial takes you from an empty folder to a working test suite in seven practical steps, with code you can copy, run and adapt for your own portfolio.
You only need basic JavaScript — variables, functions, arrow functions and objects. If you are coming from manual testing, do not worry: Cypress has one of the friendliest learning curves among automation tools, and its interactive runner shows exactly what your test is doing at every step.
Key takeaways
- Cypress runs inside the browser and automatically waits for elements and assertions, which reduces flaky tests.
- Tests are written in JavaScript or TypeScript using describe/it blocks and the cy object.
- Use dedicated data-cy attributes for stable selectors.
- cy.intercept and cy.request let you stub network calls and test APIs in the same framework.
What is Cypress?
Cypress is an open-source, JavaScript-based testing framework for modern web applications. Unlike Selenium, which drives the browser from outside through the WebDriver protocol, Cypress runs in the same run loop as your application. That gives it direct access to the DOM, network traffic and browser storage, along with features like time-travel snapshots, automatic waiting and readable error messages. It supports end-to-end and component testing, and runs on Chrome-family browsers (Chrome, Edge, Electron) and Firefox, with WebKit support marked experimental.
Cypress vs Selenium vs Playwright at a glance
| Feature | Cypress | Selenium | Playwright |
|---|---|---|---|
| Languages | JavaScript / TypeScript | Java, Python, C#, JS, Ruby | JS/TS, Python, Java, .NET |
| Auto-waiting | Built in | Explicit waits needed | Built in |
| Multiple tabs | Not supported | Supported | Supported |
| Network stubbing | cy.intercept | Limited (via CDP/BiDi) | page.route |
| Learning curve | Easy | Moderate | Easy to moderate |
For a deeper comparison, read our Playwright vs Selenium vs Cypress guide.
Prerequisites
- A current LTS version of Node.js and npm (check with node -v and npm -v).
- A code editor such as VS Code.
- Chrome, Edge or Firefox installed (Cypress also ships with Electron).
- Basic JavaScript knowledge.
Cypress tutorial: 7 steps to your first test suite
Step 1: Create a project and install Cypress
mkdir cypress-demo
cd cypress-demo
npm init -y
npm install cypress --save-dev
npx cypress openThe Launchpad opens. Choose E2E Testing, let Cypress create its configuration files, pick a browser and click to create your first spec. Cypress generates a cypress.config.js file and a cypress folder containing e2e, fixtures and support subfolders.
Step 2: Configure a base URL
Setting baseUrl lets you write cy.visit(‘/’) instead of repeating full URLs, and makes switching between QA and staging easy.
// cypress.config.js
const { defineConfig } = require('cypress');
module.exports = defineConfig({
e2e: {
baseUrl: 'https://example.cypress.io',
viewportWidth: 1280,
viewportHeight: 720,
},
});Step 3: Write your first test
Create cypress/e2e/first.cy.js. This test uses the official Cypress “Kitchen Sink” demo site:
describe('My first Cypress test', () => {
it('opens the type command page and types an email', () => {
cy.visit('/');
cy.contains('type').click();
cy.url().should('include', '/commands/actions');
cy.get('.action-email')
.type('fake@email.com')
.should('have.value', 'fake@email.com');
});
});Select the spec in the runner and watch it execute. Hover over each command in the left panel to see a snapshot of the page at that moment — this “time travel” is one of Cypress’s best debugging features.
Step 4: Use stable selectors and assertions
Cypress recommends adding dedicated attributes such as data-cy to elements, because CSS classes and text change often. Ask developers to add them, or add them yourself if you have access to the front-end code.
// HTML: <button data-cy="login-submit">Login</button>
cy.get('[data-cy=email]').type('qa.user@example.com');
cy.get('[data-cy=password]').type('Secret123', { log: false });
cy.get('[data-cy=login-submit]').click();
cy.url().should('include', '/dashboard');
cy.get('[data-cy=welcome-msg]')
.should('be.visible')
.and('contain', 'Welcome');Cypress retries cy.get and its assertions until they pass or the default timeout (4 seconds) expires, so you rarely need fixed waits. Avoid cy.wait(5000) with a number — it slows tests and hides real problems.
Step 5: Keep test data in fixtures and reuse steps with custom commands
Store data in cypress/fixtures/user.json:
{
"email": "qa.user@example.com",
"password": "Secret123"
}Then add a reusable login command in cypress/support/commands.js and use it in your specs:
// cypress/support/commands.js
Cypress.Commands.add('login', (email, password) => {
cy.visit('/login');
cy.get('[data-cy=email]').type(email);
cy.get('[data-cy=password]').type(password, { log: false });
cy.get('[data-cy=login-submit]').click();
});
// cypress/e2e/dashboard.cy.js
describe('Dashboard', () => {
beforeEach(() => {
cy.fixture('user').then((user) => {
cy.login(user.email, user.password);
});
});
it('shows the user menu', () => {
cy.get('[data-cy=user-menu]').should('be.visible');
});
});For faster suites, look at cy.session(), which caches the logged-in state between tests instead of logging in through the UI every time.
Step 6: Stub network calls and test APIs
cy.intercept lets you wait for real API calls or replace their responses with fixture data — perfect for testing empty states or error screens:
it('shows jobs from a stubbed API', () => {
cy.intercept('GET', '/api/jobs*', { fixture: 'jobs.json' }).as('getJobs');
cy.visit('/jobs');
cy.wait('@getJobs');
cy.get('[data-cy=job-card]').should('have.length', 3);
});
it('handles a server error', () => {
cy.intercept('GET', '/api/jobs*', { statusCode: 500 }).as('getJobs');
cy.visit('/jobs');
cy.wait('@getJobs');
cy.contains('Something went wrong').should('be.visible');
});cy.request sends HTTP requests directly, so you can write API tests or set up data without the UI:
it('GET a post returns 200', () => {
cy.request('https://jsonplaceholder.typicode.com/posts/1').then((response) => {
expect(response.status).to.eq(200);
expect(response.body).to.have.property('id', 1);
});
});Step 7: Run tests headlessly and in CI
# run all specs headlessly in Electron
npx cypress run
# choose a browser or a single spec
npx cypress run --browser chrome
npx cypress run --spec "cypress/e2e/dashboard.cy.js"Add these commands to package.json scripts and run them in GitHub Actions, Jenkins or GitLab CI on every pull request. Screenshots are captured automatically on failure during cypress run, and you can enable video recording in the config. Keep the project in a Git repository — our Git for testers guide covers the workflow.
Best practices from real projects
- Keep tests independent: each it block should set up its own state and not rely on the previous test.
- Prefer data-cy selectors over long CSS chains or XPath.
- Remember Cypress commands are asynchronous and chained — you cannot store cy.get results in a normal variable; use .then() or aliases.
- Set up data through APIs (cy.request) instead of the UI to save time.
- Group specs by feature and keep each spec focused on one area.
Limitations to know before interviews
Cypress supports only JavaScript and TypeScript, cannot control multiple browser tabs, and handles different origins in one test through cy.origin(). It is not meant for native mobile apps. Mentioning these trade-offs honestly in interviews shows real understanding. The official Cypress documentation is excellent and should be your main reference. If you are still planning the move into automation, our manual to automation testing guide will help you pick the right order.
🚀 Looking for Cypress and automation roles?
QA Jobs India shares 100+ fresh QA & software testing openings every morning — manual, automation, API and remote roles.
See today’s QA jobs →FAQs
Is this Cypress tutorial enough to get an automation job?
It covers the core features. Add a small framework on GitHub with 15–20 tests, CI runs and reports, plus JavaScript and API basics, and you will be interview-ready.
Is Cypress free?
The Cypress test runner is free and open source. Cypress Cloud, used for recording runs and parallelisation dashboards, has free and paid plans.
Should I learn Cypress or Playwright?
Both are in demand. Check job posts in your target companies; concepts transfer easily once you know one of them well.
Can Cypress test mobile apps?
Not native apps. You can test responsive web layouts with cy.viewport(), but native apps need tools like Appium.
Can I write Cypress tests in TypeScript?
Yes. Cypress supports TypeScript out of the box; add typescript to the project and use .cy.ts spec files.
Conclusion
You now have everything from this Cypress tutorial to build a real project: installation, configuration, first test, stable selectors, fixtures, custom commands, network stubbing, API calls and headless runs. Pick a demo website, automate its main user journeys, push the code to GitHub and add it to your resume. Then check today’s QA jobs for Cypress and automation openings.
- 100+ fresh QA jobs daily + Direct HR email IDsLive every morning at 9 AM — apply straight to HR
- Weekly Mega Job Fair800+ QA jobs from India & around the world, every week
- Certified QA coursesUp to 17 courses, with certificate
- AI ATS Resume BuilderFree resume points included
- Full LinkedQA feedEvery post, fully unblurred
- Complete QA Material libraryInterview Q&A, cheat sheets, templates & roadmaps
Instant activation right after payment · One login for jobs, courses, resume & LinkedQA
💎 Get every QA opening, every day
Join QA Jobs India Premium for 100+ verified QA jobs daily with HR contact details.