Cypress + Cursor: Smarter Code Suggestions with Rules

May 21, 2025

Introduction

Writing reliable Cypress tests can become increasingly challenging as your test suite grows. Diverse coding styles among developers lead to inconsistent test quality, brittle selectors, unclear assertions, and unnecessary debugging sessions.

Wouldn't it be helpful if your IDE could automatically guide you toward better test-writing practices? That's exactly what Cursor rules offer. In this article, we'll explore how to leverage Cursor’s context-aware rules to enhance your Cypress tests, improve maintainability, and streamline your automation workflow.

Quick Overview

Before we dive into the details, here’s a quick overview of the two tools we’ll be working with:

  • Cypress: A fast, reliable testing framework for modern web applications. It offers a rich API, automatic waiting, time-travel debugging, and a complete test runner for writing and executing end-to-end and API tests with ease.

  • Cursor: An AI-powered code editor, designed to accelerate development with intelligent code completions, in-editor chat, and context-aware suggestions that adapt to your codebase.

Now, let's explore how Cursor’s rules can help you write better Cypress tests by providing relevant and precise code suggestions.

What Are Cursor Rules?

Cursor rules aren't traditional linters—they don't enforce strict code standards or block code from compiling. Instead, they provide system-level guidance, informing Cursor's AI to generate smarter, contextually relevant suggestions.

Think of these rules as instructions that help Cursor understand your team's preferred way of writing Cypress tests, enabling AI-assisted code generation that naturally aligns with your project standards.

Why Use Cursor Rules with Cypress?

As Cypress test suites scale, inconsistencies inevitably emerge. Developers might introduce:

  • Hardcoded waits (cy.wait(1000)) causing flaky tests.
  • Fragile selectors that easily break with minor UI changes.
  • Unclear or vague test names causing confusion about test intentions.
  • Sensitive information logging and security risks.

Cursor rules help you automatically address these common pain points by guiding the AI to suggest better alternatives aligned with Cypress best practices:

  • Using aliases (cy.intercept()) instead of arbitrary waits.
  • Encouraging stable selectors (data-* attributes).
  • Ensuring thorough assertions on API calls.
  • Promoting secure handling of sensitive data.
  • Consistently generating meaningful and descriptive test names.

Rather than repeatedly reminding team members about these standards, Cursor embeds them directly into the coding experience. These are just a few examples—Cursor rules can influence nearly every aspect of how Cypress tests are written, making your test suite more maintainable, readable, and robust by default.

Example: A Complete Cypress Rule File

Here's a practical example of a Cursor rule file tailored for Cypress testing:

📄 File: .cursor/rules/cypress.mdc

---
title: Cypress Best Practices
description: Guidelines for writing clear, maintainable tests using Cypress.
type: auto_attached
alwaysApply: false
globs:
  - "cypress/**/*.{js,ts}"
  - "cypress.config.{js,ts}"
---

# Cypress Best Practices

- Tests must run independently  
- Use clear, descriptive names  
- Focus on one behavior per test  
- Initialize state with API calls, not UI  
- Reset or clean up data after each test  
- Select elements by `data-*` attributes only  
- Avoid CSS or text-based selectors  
- Rely on Cypress’s retry, not hard waits  
- Stub or alias network requests (`cy.intercept`)  
- Validate status codes and response bodies  
- Encapsulate repeats in custom commands  
- Document commands with JSDoc or TS types  
- Return Cypress chains from commands  
- Hide secrets with `log: false` and env vars  
- Store test data in fixtures or generate it  
- Use meaningful, dynamic test data  
- Write concise, meaningful assertions  
- Test both positive and negative cases  
- Keep test execution fast and cached (`cy.session`)  
- Securely manage tokens and API keys  
🔍 What’s Happening Here?

This Markdown file gives Cursor AI a clear context on how to generate or suggest code specifically within Cypress-related files. Each listed best practice directly informs Cursor's suggestions, resulting in code that's automatically closer to your desired standards.

Detailed Example: Opinionated Cypress Rule File

While the previous example focused on general Cypress best practices, this more opinionated rule file is structured for projects that follow stricter patterns or have well-established conventions. It includes guidance for organizing custom commands, referencing key folders, handling flaky patterns, and even guiding how Cursor should reason about existing code.

📄 File: .cursor/rules/cypress-opinionated.mdc

---
title: Opinionated Cypress Testing Guidelines
description: Structured recommendations for designing reliable, scalable, and maintainable Cypress tests in complex projects.
type: auto_attached
alwaysApply: false
globs:
  - "cypress/**/*.{js,ts}"
  - "cypress.config.{js,ts}"
---

# Cypress Test Guidelines

## Core Principles
- Tests must be independent and self-contained
- Tests should be self-documenting through descriptive `describe` and `it` blocks
- No JSDoc needed for test descriptions - the test names themselves are the documentation
- Comments only needed for complex setup or non-obvious test behavior

## Test Structure
- One behavior per test
- Initialize state via API calls when possible
- Use fixtures for test data, defined in [cypress/fixtures/](mdc:cypress/fixtures/)
- Let Cypress handle automatic cleanup between tests
- Only add explicit cleanup for side effects Cypress doesn't handle
- Rely on Cypress's retry mechanisms, not hard waits (avoid `cy.wait(1000)`)
- Keep test execution fast and use session caching (`cy.session`)
- Hide sensitive data with `log: false`

## Element Selection and Assertions
- Use `data-*` attributes for selectors
- Avoid brittle selectors like CSS classes or text content
- Write concise, meaningful assertions
- Test both positive and negative cases

## Custom Commands
- Primary location for custom commands is [cypress/support/](mdc:cypress/support) directory
- Commands may be split across multiple files for organization
- Commands may be defined in spec files for test-specific functionality
- Always check implementation before making assumptions
- Use existing commands directly in tests instead of creating wrapper commands
- Document commands with JSDoc or TS types
- Return Cypress chains from commands

## Network Handling
- Use `cy.intercept()` for network stubbing
- Use `cy.request()` for making network calls for API tests
- Validate response status and bodies

## Code Analysis Guidelines
Before suggesting changes:
1. Check existing patterns in the codebase
2. Review custom command implementations
3. Respect working code that follows consistent patterns
4. Don't assume missing functionality without checking implementations

## Version Compatibility
Check Cypress and all other dependencies in [package.json](mdc:package.json). Avoid using deprecated methods or syntax.

## Resources
- [Cypress Documentation](mdc:https:/docs.cypress.io)
- [Cypress Best Practices](mdc:https:/docs.cypress.io/app/core-concepts/best-practices)
- [Cypress Examples](mdc:https:/github.com/cypress-io/cypress-example-kitchensink)
🔍 What’s Happening Here?

This rule file is far more structured and opinionated than the basic example. It covers not just test patterns, but also project folder layout, network strategies, and even how Cursor should reason about the existing codebase before making suggestions.

It’s ideal for mature projects where consistency, structure, and maintainability are critical—and where AI-generated suggestions need to match deeper team conventions.

Before vs After: Cursor Rules in Action

Let's compare Cypress test code before and after enabling these Cursor rules.

❌ Before Cursor Rules:

describe('Login', () => {
  it('logs in', () => {
    cy.visit('/login');
    cy.get('#username').type('test.user@example.com');
    cy.get('#password').type('TestPassword@123');
    cy.get('button').click();
    cy.url().should('include', '/home');
  });
});
Issues:
  • Vague test description
  • Hardcoded sensitive data
  • Fragile CSS and ID selectors
  • Missing crucial assertions post-login
  • Sensitive data logged openly

✅ After Cursor Rules Applied:

describe('Login Page', () => {
  it('successfully logs in with valid credentials and displays dashboard', () => {
    cy.visit('/login');
    cy.get('[data-testid="input:username"]').type(Cypress.env('TEST_USERNAME'));
    cy.get('[data-testid="input:password"]').type(Cypress.env('TEST_PASSWORD'), { log: false });
    cy.get('[data-testid="button:login"]').click();
    cy.url().should('include', '/home');
    cy.get('[data-testid="dashboard-welcome"]').should('be.visible');
  });
});
Improvements:
  • Clearly described test behavior
  • Secure and dynamic handling of credentials
  • Robust data-testid selectors
  • Explicit assertion verifying post-login state

Cursor automatically suggested these improvements based solely on the context provided by the rule file.

Adding Cursor Rules to Your Cypress Project

Integrating Cursor rules into your Cypress workflow is straightforward:

  1. Create a .cursor/rules/ folder at your project's root.
  2. Add your .mdc rule files (such as the above cypress.mdc) to this directory.

Once added, Cursor automatically uses these rules as context when you're editing matching files, shaping code completions and suggestions accordingly.

Tailoring Rules to Your Project

Your tests will evolve, and so should your rules. Cursor allows easy iteration:

  • Use the /Generate Cursor Rules command to automatically generate rules from your current Cypress tests.
  • Regularly refine these rules to keep them relevant as you adopt new Cypress patterns, commands, or team standards.
  • Create specialized rules for different parts of your test suite (e.g., API tests, UI tests, custom commands).

Wrapping Up

Cursor rules are a powerful feature that continuously enhances your development workflow. The more accurately they reflect your team's real-world practices, the better and more consistent your test code will become.

References


Profile picture

Darpan Shah

Dedication to software quality is what you'll find here front and center. Dive into insights, challenges, and solutions drawn from my experiences.