An ESLint plugin for projects using Cypress that provides comprehensive linting rules to enforce best practices for writing Cypress tests
npx @tessl/cli install tessl/npm-eslint-plugin-cypress@5.1.0ESLint Plugin Cypress is an ESLint plugin that provides comprehensive linting rules specifically designed for Cypress test projects. It enforces best practices for writing Cypress tests, helps catch common anti-patterns, and provides pre-configured rule sets to improve code quality in Cypress test suites.
npm install eslint-plugin-cypress --save-devimport pluginCypress from 'eslint-plugin-cypress';For CommonJS:
const pluginCypress = require('eslint-plugin-cypress');Recommended Setup:
// eslint.config.mjs
import pluginCypress from 'eslint-plugin-cypress';
export default [
// Use recommended configuration with globals and core rules
pluginCypress.configs.recommended
];Custom Configuration:
// eslint.config.mjs
import pluginCypress from 'eslint-plugin-cypress';
export default [
// Use globals only and configure rules manually
pluginCypress.configs.globals,
{
rules: {
'cypress/no-assigning-return-values': 'error',
'cypress/no-unnecessary-waiting': 'warn',
'cypress/no-debug': 'error',
'cypress/require-data-selectors': 'warn'
}
}
];File-Specific Configuration:
// eslint.config.mjs
import pluginCypress from 'eslint-plugin-cypress';
export default [
// Apply Cypress rules only to test files
{
files: ['cypress/**/*.{js,ts}', '**/*.cy.{js,ts}'],
...pluginCypress.configs.recommended
}
];ESLint Plugin Cypress is built around several key components:
globals and recommended) for different use casesCore plugin interface providing access to rules and configuration presets for ESLint integration.
interface CypressPlugin {
meta: {
name: string;
version: string;
};
rules: {
[ruleName: string]: ESLintRule;
};
configs: {
globals: ESLintConfig;
recommended: ESLintConfig;
};
}
const plugin: CypressPlugin;Collection of 12 specialized ESLint rules that detect Cypress-specific code patterns and anti-patterns. Rules are categorized into problem-type rules (7 rules) that catch potential errors and suggestion-type rules (5 rules) that enforce best practices.
interface RuleCollection {
'assertion-before-screenshot': ESLintRule;
'no-assigning-return-values': ESLintRule;
'no-async-before': ESLintRule;
'no-async-tests': ESLintRule;
'no-chained-get': ESLintRule;
'no-debug': ESLintRule;
'no-force': ESLintRule;
'no-pause': ESLintRule;
'no-unnecessary-waiting': ESLintRule;
'no-xpath': ESLintRule;
'require-data-selectors': ESLintRule;
'unsafe-to-chain-command': ESLintRule;
}Pre-configured ESLint configurations providing different levels of Cypress linting support, from basic globals definitions to comprehensive recommended rule sets.
interface ConfigPresets {
globals: {
name: string;
plugins: { cypress: CypressPlugin };
languageOptions: {
globals: GlobalsDefinition;
};
};
recommended: {
name: string;
plugins: { cypress: CypressPlugin };
rules: {
'cypress/no-assigning-return-values': 'error';
'cypress/no-unnecessary-waiting': 'error';
'cypress/no-async-tests': 'error';
'cypress/unsafe-to-chain-command': 'error';
};
languageOptions: {
globals: GlobalsDefinition;
};
};
}
interface GlobalsDefinition {
cy: false;
Cypress: false;
expect: false;
assert: false;
chai: false;
// Plus browser and mocha globals
}interface ESLintRule {
meta: {
type: 'problem' | 'suggestion';
docs: {
description: string;
category?: string;
recommended: boolean;
url: string;
};
schema: any[];
messages: {
[messageId: string]: string;
};
};
create(context: ESLintContext): ESLintVisitor;
}
interface ESLintConfig {
name: string;
plugins?: { [pluginName: string]: any };
rules?: { [ruleName: string]: string | string[] };
languageOptions?: {
globals?: { [globalName: string]: boolean | 'off' | 'readonly' | 'writable' };
};
}
interface ESLintContext {
/** Report a linting issue at a specific node */
report(options: { node: any; messageId: string; data?: any }): void;
/** Get the source code object for accessing code and ancestors */
getSourceCode?(): SourceCode;
sourceCode?: SourceCode;
/** Get ancestors of a node (deprecated in favor of sourceCode.getAncestors) */
getAncestors?(): any[];
}
interface SourceCode {
/** Get ancestors of a node in the AST */
getAncestors?(node: any): any[];
}
interface ESLintVisitor {
/** Visit CallExpression nodes (function calls) */
CallExpression?(node: any): void;
/** Visit Identifier nodes (variable names, function names) */
Identifier?(node: any): void;
/** Visit VariableDeclaration nodes (var, let, const declarations) */
VariableDeclaration?(node: any): void;
/** Visit any other AST node types as needed by specific rules */
[nodeType: string]: ((node: any) => void) | undefined;
}