Skip to content

Commit 0508b75

Browse files
fix: dont throw warning on variable data selector (#272)
* fix: dont throw warning on variable data selector * fix: use Set instead of Map, as we dont reuse the value * Update lib/rules/require-data-selectors.js Co-authored-by: Jennifer Shehane <[email protected]> --------- Co-authored-by: Jennifer Shehane <[email protected]>
1 parent 3fcfb93 commit 0508b75

File tree

3 files changed

+52
-8
lines changed

3 files changed

+52
-8
lines changed

docs/rules/require-data-selectors.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,22 @@ cy.get('[daedta-cy=submit]').click()
1616
cy.get('[d-cy=submit]')
1717
cy.get('.btn-large').click()
1818
cy.get('.btn-.large').click()
19+
20+
const CLASS_SELECTOR = ".my-class";
21+
cy.get(CLASS_SELECTOR)
1922
```
2023

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

2326
```js
2427
cy.get('[data-cy=submit]').click()
2528
cy.get('[data-QA=submit]')
29+
cy.get(`[data-QA=submit]`)
30+
```
31+
32+
```js
33+
const ASSESSMENT_SUBMIT = "[data-cy=assessment-submit]"
34+
cy.get(ASSESSMENT_SUBMIT).click()
2635
```
2736

2837
## Further Reading

lib/rules/require-data-selectors.js

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
'use strict'
2-
32
module.exports = {
43
meta: {
54
type: 'suggestion',
@@ -16,9 +15,29 @@ module.exports = {
1615
},
1716

1817
create(context) {
18+
const variablesSet = new Set()
1919
return {
20+
VariableDeclarator(node) {
21+
if (node.init && node.id && node.id.type === 'Identifier') {
22+
let selectorValue = null
23+
24+
if (node.init.type === 'Literal' && typeof node.init.value === 'string') {
25+
selectorValue = node.init.value
26+
}
27+
else if (node.init.type === 'TemplateLiteral'
28+
&& node.init.expressions.length === 0
29+
&& node.init.quasis.length === 1) {
30+
selectorValue = node.init.quasis[0].value.cooked
31+
}
32+
33+
if (selectorValue && isAliasOrDataSelector(selectorValue)) {
34+
variablesSet.add(node.id.name)
35+
}
36+
}
37+
},
38+
2039
CallExpression(node) {
21-
if (isCallingCyGet(node) && !isDataArgument(node)) {
40+
if (isCallingCyGet(node) && !isDataArgument(node, variablesSet)) {
2241
context.report({ node, messageId: 'unexpected' })
2342
}
2443
},
@@ -34,12 +53,24 @@ function isCallingCyGet(node) {
3453
&& node.callee.property.name === 'get'
3554
}
3655

37-
function isDataArgument(node) {
38-
return node.arguments.length > 0
39-
&& (
40-
(node.arguments[0].type === 'Literal' && isAliasOrDataSelector(String(node.arguments[0].value)))
41-
|| (node.arguments[0].type === 'TemplateLiteral' && isAliasOrDataSelector(String(node.arguments[0].quasis[0].value.cooked)))
42-
)
56+
function isDataArgument(node, dataVariables) {
57+
if (node.arguments.length === 0) return false
58+
59+
const firstArg = node.arguments[0]
60+
61+
if (firstArg.type === 'Literal') {
62+
return isAliasOrDataSelector(String(firstArg.value))
63+
}
64+
65+
if (firstArg.type === 'TemplateLiteral') {
66+
return isAliasOrDataSelector(String(firstArg.quasis[0].value.cooked))
67+
}
68+
69+
if (firstArg.type === 'Identifier') {
70+
return dataVariables.has(firstArg.name)
71+
}
72+
73+
return false
4374
}
4475

4576
function isAliasOrDataSelector(selector) {

tests/lib/rules/require-data-selectors.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ ruleTester.run('require-data-selectors', rule, {
1717
{ code: 'cy.get(\`[data-cy=${1}]\`)' }, // eslint-disable-line no-useless-escape
1818
{ code: 'cy.get("@my-alias")' },
1919
{ code: 'cy.get(`@my-alias`)' },
20+
{ code: 'const ASSESSMENT_SUBMIT = "[data-cy=assessment-submit]"; cy.get(ASSESSMENT_SUBMIT)' },
21+
{ code: 'const ALIAS_TEMPLATE = `@my-alias`; cy.get(ALIAS_TEMPLATE)' },
2022
],
2123

2224
invalid: [
@@ -26,5 +28,7 @@ ruleTester.run('require-data-selectors', rule, {
2628
{ code: 'cy.get(".btn-.large").click()', errors },
2729
{ code: 'cy.get(".a")', errors },
2830
{ code: 'cy.get(\`[daedta-cy=${1}]\`)', errors }, // eslint-disable-line no-useless-escape
31+
{ code: 'const BAD_SELECTOR = ".my-class"; cy.get(BAD_SELECTOR)', errors },
32+
{ code: 'const GOOD = "[data-cy=good]"; const BAD = ".bad"; cy.get(GOOD); cy.get(BAD)', errors },
2933
],
3034
})

0 commit comments

Comments
 (0)