diff --git a/README.md b/README.md index b65c58f..7586bf4 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,8 @@ You can add rules: "cypress/no-force": "warn", "cypress/no-async-tests": "error", "cypress/no-async-before": "error", - "cypress/no-pause": "error" + "cypress/no-pause": "error", + "cypress/no-debug": "error" } } ``` @@ -133,6 +134,7 @@ These rules enforce some of the [best practices recommended for using Cypress](h | [no-assigning-return-values](docs/rules/no-assigning-return-values.md) | disallow assigning return values of `cy` calls | ✅ | | [no-async-before](docs/rules/no-async-before.md) | disallow using `async`/`await` in Cypress `before` methods | | | [no-async-tests](docs/rules/no-async-tests.md) | disallow using `async`/`await` in Cypress test cases | ✅ | +| [no-debug](docs/rules/no-debug.md) | disallow using `cy.debug()` calls | | | [no-force](docs/rules/no-force.md) | disallow using `force: true` with action commands | | | [no-pause](docs/rules/no-pause.md) | disallow using `cy.pause()` calls | | | [no-unnecessary-waiting](docs/rules/no-unnecessary-waiting.md) | disallow waiting for arbitrary time periods | ✅ | diff --git a/docs/rules/no-debug.md b/docs/rules/no-debug.md new file mode 100644 index 0000000..5f2145b --- /dev/null +++ b/docs/rules/no-debug.md @@ -0,0 +1,19 @@ +# Disallow using `cy.debug()` calls (`cypress/no-debug`) + + +It is recommended to remove any [cy.debug](https://on.cypress.io/debug) commands before committing specs to avoid other developers getting unexpected results. + +## Rule Details + +Examples of **incorrect** code for this rule: + +```js +cy.debug(); +cy.get('selector').debug(); +``` + +Examples of **correct** code for this rule: + +```js +cy.get('selector') +``` diff --git a/legacy.js b/legacy.js index a615be9..36f2b78 100644 --- a/legacy.js +++ b/legacy.js @@ -11,6 +11,7 @@ module.exports = { 'require-data-selectors': require('./lib/rules/require-data-selectors'), 'no-force': require('./lib/rules/no-force'), 'no-pause': require('./lib/rules/no-pause'), + 'no-debug': require('./lib/rules/no-debug'), }, configs: { recommended: require('./lib/config/recommended'), diff --git a/lib/flat.js b/lib/flat.js index c596ab5..038a580 100644 --- a/lib/flat.js +++ b/lib/flat.js @@ -14,6 +14,7 @@ const plugin = { 'require-data-selectors': require('./rules/require-data-selectors'), 'no-force': require('./rules/no-force'), 'no-pause': require('./rules/no-pause'), + 'no-debug': require('./rules/no-debug'), }, } diff --git a/lib/rules/no-debug.js b/lib/rules/no-debug.js new file mode 100644 index 0000000..c94ebf9 --- /dev/null +++ b/lib/rules/no-debug.js @@ -0,0 +1,61 @@ +'use strict' + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + type: 'suggestion', + docs: { + description: 'disallow using `cy.debug()` calls', + category: 'Possible Errors', + recommended: false, + url: 'https://github.com/cypress-io/eslint-plugin-cypress/blob/master/docs/rules/no-debug.md', + }, + fixable: null, // or "code" or "whitespace" + schema: [], + messages: { + unexpected: 'Do not use cy.debug command', + }, + }, + + create (context) { + + // variables should be defined here + + //---------------------------------------------------------------------- + // Helpers + //---------------------------------------------------------------------- + function isCallingDebug (node) { + return node.callee && + node.callee.property && + node.callee.property.type === 'Identifier' && + node.callee.property.name === 'debug' + } + + function isCypressCall (node) { + if (!node.callee || node.callee.type !== 'MemberExpression') { + return false; + } + if (node.callee.object.type === 'Identifier' && node.callee.object.name === 'cy') { + return true; + } + return isCypressCall(node.callee.object); + } + + //---------------------------------------------------------------------- + // Public + //---------------------------------------------------------------------- + + return { + + CallExpression (node) { + if (isCypressCall(node) && isCallingDebug(node)) { + context.report({ node, messageId: 'unexpected' }) + } + }, + + } + }, +} diff --git a/tests/lib/rules/no-debug.js b/tests/lib/rules/no-debug.js new file mode 100644 index 0000000..f48693e --- /dev/null +++ b/tests/lib/rules/no-debug.js @@ -0,0 +1,23 @@ +'use strict' + +const rule = require('../../../lib/rules/no-debug') +const RuleTester = require('eslint').RuleTester + +const ruleTester = new RuleTester() + +const errors = [{ messageId: 'unexpected' }] + +ruleTester.run('no-debug', rule, { + + valid: [ + { code: `debug()` }, + { code: `cy.get('button').dblclick()` }, + ], + + invalid: [ + { code: `cy.debug()`, errors }, + { code: `cy.debug({ log: false })`, errors }, + { code: `cy.get('button').debug()`, errors }, + { code: `cy.get('a').should('have.attr', 'href').and('match', /dashboard/).debug()`, errors } + ], +})