Skip to content

Commit

Permalink
feat: add rule disallow usage of cypress-xpath
Browse files Browse the repository at this point in the history
  • Loading branch information
duranbe committed Mar 2, 2025
1 parent 19842d3 commit 1ae902a
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 0 deletions.
27 changes: 27 additions & 0 deletions docs/rules/no-xpath.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Disallow usage of cypress xpath (`no-xpath`)

This rule disallow the usage of cypress-xpath for selecting elements.


Examples of **incorrect** code for this rule:

```js

cy.xpath('//div[@class=\"container\"]').click()
```

Examples of **correct** code for this rule:


```js

cy.get('[data-cy="container"]').click();
```


## Further Reading

`cypress-xpath` package has been deprecated since Oct 13, 2022.


See [the Cypress Best Practices guide](https://docs.cypress.io/guides/references/best-practices.html#Selecting-Elements).
1 change: 1 addition & 0 deletions legacy.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ module.exports = {
'no-force': require('./lib/rules/no-force'),
'no-pause': require('./lib/rules/no-pause'),
'no-debug': require('./lib/rules/no-debug'),
'no-xpath': require('./lib/rules/no-xpath'),
},
configs: {
recommended: require('./lib/config/recommended'),
Expand Down
1 change: 1 addition & 0 deletions lib/flat.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const plugin = {
'no-force': require('./rules/no-force'),
'no-pause': require('./rules/no-pause'),
'no-debug': require('./rules/no-debug'),
'no-xpath': require('./rules/no-xpath'),
},
}

Expand Down
35 changes: 35 additions & 0 deletions lib/rules/no-xpath.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
'use strict'

module.exports = {
meta: {
type: 'suggestion',
docs: {
description: "disallow usage of xpath in selector",
recommended: false,
url: "https://github.com/cypress-io/eslint-plugin-cypress/blob/master/docs/rules/no-xpath.md"
},
fixable: null, // Or `code` or `whitespace`
schema: [], // Add a schema if the rule has options
messages: {
unexpected: 'avoid using cypress xpath',
},
},

create (context) {
return {
CallExpression (node) {
if (isCallingCyXpath(node)) {
context.report({ node, messageId: 'unexpected' })
}
},
}
},
};

function isCallingCyXpath (node) {
return node.callee.type === 'MemberExpression' &&
node.callee.object.type === 'Identifier' &&
node.callee.object.name === 'cy' &&
node.callee.property.type === 'Identifier' &&
node.callee.property.name === 'xpath'
}
31 changes: 31 additions & 0 deletions tests/lib/rules/no-xpath.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"use strict";

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------

const rule = require("../../../lib/rules/no-xpath"),
RuleTester = require("eslint").RuleTester;

//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------

const ruleTester = new RuleTester();
ruleTester.run("no-xpath", rule, {
valid: [
{ code: 'cy.wait("@someRequest")' },
{ code: 'cy.get("button").click({force: true})' },
],

invalid: [
{
code: "cy.xpath('//div[@class=\"container\"]/p[1]').click()",
errors: [{ messageId: "unexpected" }],
},
{
code: "cy.xpath('//p[1]').should('exist')",
errors: [{ messageId: "unexpected" }]
}
],
});

0 comments on commit 1ae902a

Please sign in to comment.