Master Cypress for developer-friendly testing with real-time reloading and powerful debugging
Cypress is like having a developer-friendly testing assistant. It runs in the browser, gives you real-time feedback, and makes debugging a breeze.
✓ Time Travel
See what happened at each step
✓ Real-time Reload
Tests update as you code
✓ Automatic Waiting
No manual waits needed
✓ Network Control
Stub and spy on requests
# Install Cypress
npm install cypress --save-dev
# Open Cypress
npx cypress open
# Run tests headless
npx cypress run
cypress/
├── e2e/ # Test files
├── fixtures/ # Test data
├── support/ # Custom commands
└── cypress.config.js # Configuration
// cypress/e2e/login.cy.js
describe('Login Tests', () => {
beforeEach(() => {
// Run before each test
cy.visit('/login');
});
it('should login successfully', () => {
// Type into fields
cy.get('[data-cy="email"]').type('test@email.com');
cy.get('[data-cy="password"]').type('password123');
// Click button
cy.get('[data-cy="submit"]').click();
// Verify redirect
cy.url().should('include', '/dashboard');
cy.contains('Welcome back').should('be.visible');
});
it('should show error for invalid credentials', () => {
cy.get('[data-cy="email"]').type('wrong@email.com');
cy.get('[data-cy="password"]').type('wrongpass');
cy.get('[data-cy="submit"]').click();
cy.get('.error-message')
.should('be.visible')
.and('contain', 'Invalid credentials');
});
});
Create reusable commands to avoid repeating code. Think of them as shortcuts for common actions.
// 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);
cy.get('[data-cy="submit"]').click();
cy.url().should('include', '/dashboard');
});
Cypress.Commands.add('addToCart', (productName) => {
cy.contains('.product-card', productName)
.find('button')
.click();
cy.get('.cart-count').should('be.visible');
});
// Using custom commands
it('should add products to cart', () => {
cy.login('test@email.com', 'password123');
cy.addToCart('Product 1');
cy.addToCart('Product 2');
});
// Test API endpoints
describe('API Tests', () => {
it('should fetch users', () => {
cy.request('GET', '/api/users')
.then((response) => {
expect(response.status).to.eq(200);
expect(response.body).to.have.length(10);
expect(response.body[0]).to.have.property('name');
});
});
it('should create user', () => {
cy.request({
method: 'POST',
url: '/api/users',
body: {
name: 'Test User',
email: 'test@email.com'
}
}).then((response) => {
expect(response.status).to.eq(201);
expect(response.body).to.have.property('id');
});
});
});
// Intercept and stub API calls
it('should mock API response', () => {
cy.intercept('GET', '/api/users', {
statusCode: 200,
body: [{ id: 1, name: 'Mocked User' }]
}).as('getUsers');
cy.visit('/users');
cy.wait('@getUsers');
cy.contains('Mocked User').should('be.visible');
});
Catch visual bugs by comparing screenshots. Like having a robot that notices if buttons moved or colors changed.
# Install plugin
npm install --save-dev cypress-image-snapshot
// cypress/support/e2e.js
import 'cypress-image-snapshot/command';
// Take baseline screenshot
it('should match homepage design', () => {
cy.visit('/');
cy.matchImageSnapshot('homepage');
});
// Compare specific element
it('should match header design', () => {
cy.visit('/');
cy.get('.header').matchImageSnapshot('header');
});
Test React/Vue components in isolation without running the entire app.
// cypress/component/Button.cy.jsx
import Button from '../../src/components/Button';
describe('Button Component', () => {
it('should render with text', () => {
cy.mount(<Button> Click Me</Button> );
cy.contains('Click Me').should('be.visible');
});
it('should call onClick when clicked', () => {
const onClickSpy = cy.spy().as('onClickSpy');
cy.mount(<Button onClick={onClickSpy}> Click</Button> );
cy.contains('Click').click();
cy.get('@onClickSpy').should('have.been.calledOnce');
});
it('should be disabled', () => {
cy.mount(<Button disabled> Disabled</Button> );
cy.contains('Disabled').should('be.disabled');
});
});
Cypress Cloud provides test recording, parallelization, and detailed analytics.
# Setup Cypress Cloud
npx cypress run --record --key YOUR_RECORD_KEY
// cypress.config.js
module.exports = defineConfig({
projectId: 'your-project-id',
e2e: {
video: true,
screenshotOnRunFailure: true,
reporter: 'mochawesome',
reporterOptions: {
reportDir: 'cypress/reports',
overwrite: false,
html: true,
json: true
}
}
});
Complete test suite for a social media application.
// cypress/e2e/social-media.cy.js
describe('Social Media App', () => {
beforeEach(() => {
cy.login('user@test.com', 'password123');
});
it('should create a post', () => {
cy.get('[data-cy="new-post"]').click();
cy.get('[data-cy="post-content"]')
.type('This is my test post!');
cy.get('[data-cy="post-submit"]').click();
cy.contains('This is my test post!')
.should('be.visible');
});
it('should like a post', () => {
cy.get('.post').first()
.find('[data-cy="like-button"]')
.click();
cy.get('.post').first()
.find('.like-count')
.should('contain', '1');
});
it('should comment on post', () => {
cy.get('.post').first()
.find('[data-cy="comment-input"]')
.type('Great post!');
cy.get('.post').first()
.find('[data-cy="comment-submit"]')
.click();
cy.contains('Great post!').should('be.visible');
});
});
You've mastered Cypress for advanced web testing:
Next: API Testing & Automation in Module 4!