CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-eslint-plugin-cypress

An ESLint plugin for projects using Cypress that provides comprehensive linting rules to enforce best practices for writing Cypress tests

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

rules.mddocs/

Lint Rules

Collection of specialized ESLint rules that detect Cypress-specific code patterns and anti-patterns. The plugin provides 12 rules categorized into problem-type rules that catch potential errors and suggestion-type rules that enforce best practices.

Capabilities

Problem-Type Rules

Rules that detect code patterns likely to cause runtime errors or unexpected behavior in Cypress tests.

assertion-before-screenshot

Requires screenshots to be preceded by an assertion to ensure test stability.

/**
 * Requires screenshots to be preceded by an assertion
 * Category: Possible Errors
 * Recommended: false
 * Type: problem
 */
'assertion-before-screenshot': ESLintRule;

Usage Example:

// ❌ Incorrect - Screenshot without preceding assertion
cy.visit('/dashboard');
cy.screenshot('dashboard');

// ✅ Correct - Screenshot preceded by assertion
cy.visit('/dashboard');
cy.get('[data-cy=header]').should('be.visible');
cy.screenshot('dashboard');

// ✅ Correct - Multiple assertions before screenshot
cy.visit('/user-profile');
cy.get('[data-cy=avatar]').should('be.visible');
cy.get('[data-cy=user-name]').should('contain', 'John Doe');
cy.screenshot('user-profile-loaded');

no-assigning-return-values

Disallows assigning return values of cy calls, as Cypress commands return chainable objects rather than actual values.

/**
 * Disallows assigning return values of cy calls
 * Category: Possible Errors
 * Recommended: true (included in recommended config)
 * Type: problem
 */
'no-assigning-return-values': ESLintRule;

Usage Example:

// ❌ Incorrect - Cypress commands don't return actual values
const text = cy.get('[data-cy=element]').text();

// ✅ Correct - Use then() to access values
cy.get('[data-cy=element]').then(($el) => {
  const text = $el.text();
});

no-async-before

Disallows using async/await in Cypress before methods, as they can cause timing issues.

/**
 * Disallows using async/await in Cypress before methods
 * Category: Possible Errors
 * Recommended: false
 * Type: problem
 */
'no-async-before': ESLintRule;

no-async-tests

Disallows using async/await in Cypress test cases, as Cypress handles asynchronous operations automatically.

/**
 * Disallows using async/await in Cypress test cases
 * Category: Possible Errors
 * Recommended: true (included in recommended config)
 * Type: problem
 */
'no-async-tests': ESLintRule;

no-unnecessary-waiting

Disallows waiting for arbitrary time periods, promoting more reliable test patterns.

/**
 * Disallows waiting for arbitrary time periods
 * Category: Possible Errors
 * Recommended: true (included in recommended config)
 * Type: problem
 */
'no-unnecessary-waiting': ESLintRule;

Usage Example:

// ❌ Incorrect - Arbitrary waiting
cy.wait(5000);

// ✅ Correct - Wait for specific conditions
cy.wait('@apiRequest');
cy.get('[data-cy=loading]').should('not.exist');

unsafe-to-chain-command

Disallows actions within chains that can cause race conditions or unreliable test behavior.

/**
 * Disallows actions within chains
 * Category: Possible Errors
 * Recommended: true (included in recommended config)
 * Type: problem
 */
'unsafe-to-chain-command': ESLintRule;

Usage Example:

// ❌ Incorrect - Actions in the middle of chains are unsafe
cy.get('[data-cy=input]')
  .clear()          // Unsafe action
  .type('new text')
  .should('have.value', 'new text');

cy.get('[data-cy=button]')
  .click()          // Unsafe action
  .should('not.exist');

// ✅ Correct - Actions at the end of chains
cy.get('[data-cy=input]').clear();
cy.get('[data-cy=input]').type('new text');
cy.get('[data-cy=input]').should('have.value', 'new text');

cy.get('[data-cy=button]').should('be.visible');
cy.get('[data-cy=button]').click();

Suggestion-Type Rules

Rules that enforce best practices and coding standards for Cypress test maintainability.

no-chained-get

Disallows chaining multiple cy.get() calls, which can lead to confusing test logic.

/**
 * Disallows chain of cy.get() calls
 * Category: (not specified)
 * Recommended: false
 * Type: problem
 */
'no-chained-get': ESLintRule;

Usage Example:

// ❌ Incorrect - Chaining multiple cy.get() calls
cy.get('[data-cy=parent]')
  .get('[data-cy=child]')
  .click();

// ✅ Correct - Use find() or within() to scope searches
cy.get('[data-cy=parent]')
  .find('[data-cy=child]')
  .click();

// ✅ Correct - Use within() for scoped operations
cy.get('[data-cy=parent]').within(() => {
  cy.get('[data-cy=child]').click();
});

// ✅ Correct - Separate get() calls for different elements
cy.get('[data-cy=parent]').should('be.visible');
cy.get('[data-cy=child]').click();

no-debug

Disallows using cy.debug() calls in production test code to prevent debugging code from being committed.

/**
 * Disallows using cy.debug() calls
 * Category: Possible Errors
 * Recommended: false
 * Type: suggestion
 */
'no-debug': ESLintRule;

no-force

Disallows using force: true with action commands, encouraging proper element interaction patterns.

/**
 * Disallows using force: true with action commands
 * Category: Possible Errors
 * Recommended: false
 * Type: suggestion
 */
'no-force': ESLintRule;

Usage Example:

// ❌ Discouraged - Using force bypasses actionability checks
cy.get('button').click({ force: true });

// ✅ Better - Ensure element is actionable
cy.get('button').should('be.visible').click();

no-pause

Disallows using cy.pause() calls to prevent debugging code from being committed to production.

/**
 * Disallows using cy.pause() calls
 * Category: Possible Errors
 * Recommended: false
 * Type: suggestion
 */
'no-pause': ESLintRule;

no-xpath

Disallows using cy.xpath() calls, encouraging the use of more maintainable CSS selectors.

/**
 * Disallows using cy.xpath() calls
 * Category: (not specified)
 * Recommended: false
 * Type: suggestion
 */
'no-xpath': ESLintRule;

require-data-selectors

Requires data-* attribute selectors to promote stable, maintainable test selectors.

/**
 * Requires data-* attribute selectors
 * Category: Possible Errors
 * Recommended: false
 * Type: suggestion
 */
'require-data-selectors': ESLintRule;

Usage Example:

// ❌ Discouraged - Fragile selectors
cy.get('.btn-primary');
cy.get('#submit-button');

// ✅ Preferred - Stable data attributes
cy.get('[data-cy=submit-button]');
cy.get('[data-testid=user-profile]');

Rule Categories

By Recommendation Status

Recommended Rules (4) - Included in configs.recommended:

  • no-assigning-return-values
  • no-async-tests
  • no-unnecessary-waiting
  • unsafe-to-chain-command

Optional Rules (8) - Available but not enabled by default:

  • assertion-before-screenshot
  • no-async-before
  • no-chained-get
  • no-debug
  • no-force
  • no-pause
  • no-xpath
  • require-data-selectors

By Rule Type

Problem Rules (7) - Detect likely errors:

  • assertion-before-screenshot
  • no-assigning-return-values
  • no-async-before
  • no-async-tests
  • no-chained-get
  • no-unnecessary-waiting
  • unsafe-to-chain-command

Suggestion Rules (5) - Enforce best practices:

  • no-debug
  • no-force
  • no-pause
  • no-xpath
  • require-data-selectors

Rule Configuration

All rules can be individually configured in ESLint configuration:

export default [
  {
    plugins: {
      cypress: pluginCypress
    },
    rules: {
      // Error level
      'cypress/no-assigning-return-values': 'error',
      
      // Warning level
      'cypress/no-unnecessary-waiting': 'warn',
      
      // Disabled
      'cypress/no-debug': 'off'
    }
  }
];

Install with Tessl CLI

npx tessl i tessl/npm-eslint-plugin-cypress

docs

configurations.md

index.md

rules.md

tile.json