eslint-plugin-cypress 4.3.0 → 5.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.node-version +1 -1
- package/.nvmrc +1 -1
- package/CONTRIBUTING.md +2 -7
- package/ESLINTRC-CONFIG.md +3 -143
- package/FLAT-CONFIG.md +1 -3
- package/README.md +25 -19
- package/circle.yml +2 -20
- package/eslint.config.mjs +13 -6
- package/lib/flat.js +14 -14
- package/lib/rules/assertion-before-screenshot.js +21 -21
- package/lib/rules/no-assigning-return-values.js +4 -4
- package/lib/rules/no-async-before.js +10 -10
- package/lib/rules/no-async-tests.js +10 -10
- package/lib/rules/no-chained-get.js +32 -32
- package/lib/rules/no-debug.js +18 -19
- package/lib/rules/no-force.js +21 -24
- package/lib/rules/no-pause.js +18 -19
- package/lib/rules/no-unnecessary-waiting.js +13 -13
- package/lib/rules/no-xpath.js +10 -10
- package/lib/rules/require-data-selectors.js +14 -14
- package/lib/rules/unsafe-to-chain-command.js +13 -13
- package/package.json +12 -14
- package/test-project/eslint-configs/eslint.default-deprecated.mjs +11 -0
- package/test-project/eslint-configs/eslint.default.mjs +1 -1
- package/test-project/eslint-configs/eslint.globals.mjs +1 -1
- package/test-project/eslint-configs/eslint.recommended.mjs +1 -1
- package/tests/lib/rules/no-chained-get.js +15 -15
- package/tests/lib/rules/no-debug.js +6 -6
- package/tests/lib/rules/no-force.js +22 -22
- package/tests/lib/rules/no-pause.js +6 -6
- package/tests/lib/rules/no-xpath.js +15 -15
- package/tests/lib/rules/unsafe-to-chain-command.js +1 -1
- package/vitest.config.mts +8 -0
- package/jest.config-legacy.js +0 -6
- package/jest.config.js +0 -6
- package/legacy.js +0 -36
- package/tests-legacy/config.js +0 -26
- package/tests-legacy/lib/rules/assertion-before-screenshot.js +0 -35
- package/tests-legacy/lib/rules/no-assigning-return-values.js +0 -38
- package/tests-legacy/lib/rules/no-async-before.js +0 -25
- package/tests-legacy/lib/rules/no-async-tests.js +0 -25
- package/tests-legacy/lib/rules/no-force.js +0 -49
- package/tests-legacy/lib/rules/no-pause.js +0 -37
- package/tests-legacy/lib/rules/no-unnecessary-waiting.js +0 -71
- package/tests-legacy/lib/rules/require-data-selectors.js +0 -31
- package/tests-legacy/lib/rules/unsafe-to-chain-command.js +0 -56
|
@@ -15,31 +15,31 @@ module.exports = {
|
|
|
15
15
|
},
|
|
16
16
|
},
|
|
17
17
|
|
|
18
|
-
create
|
|
19
|
-
function isTestBlock
|
|
18
|
+
create(context) {
|
|
19
|
+
function isTestBlock(callExpressionNode) {
|
|
20
20
|
const { type, name } = callExpressionNode.callee
|
|
21
21
|
|
|
22
22
|
return type === 'Identifier'
|
|
23
|
-
|
|
23
|
+
&& (name === 'it' || name === 'test')
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
function isTestAsync
|
|
26
|
+
function isTestAsync(node) {
|
|
27
27
|
return node.arguments
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
&& node.arguments.length >= 2
|
|
29
|
+
&& node.arguments[1].async === true
|
|
30
30
|
}
|
|
31
31
|
const sourceCode = context.sourceCode ?? context.getSourceCode()
|
|
32
32
|
|
|
33
33
|
return {
|
|
34
|
-
Identifier
|
|
34
|
+
Identifier(node) {
|
|
35
35
|
if (node.name === 'cy' || node.name === 'Cypress') {
|
|
36
36
|
const ancestors = sourceCode.getAncestors
|
|
37
37
|
? sourceCode.getAncestors(node)
|
|
38
38
|
: context.getAncestors()
|
|
39
39
|
const asyncTestBlocks = ancestors
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
.filter((n) => n.type === 'CallExpression')
|
|
41
|
+
.filter(isTestBlock)
|
|
42
|
+
.filter(isTestAsync)
|
|
43
43
|
|
|
44
44
|
if (asyncTestBlocks.length >= 1) {
|
|
45
45
|
asyncTestBlocks.forEach((node) => {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
'use strict'
|
|
1
|
+
'use strict'
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
// ------------------------------------------------------------------------------
|
|
4
4
|
// Rule Definition
|
|
5
|
-
|
|
5
|
+
// ------------------------------------------------------------------------------
|
|
6
6
|
|
|
7
7
|
/** @type {import('eslint').Rule.RuleModule} */
|
|
8
8
|
module.exports = {
|
|
@@ -23,55 +23,55 @@ module.exports = {
|
|
|
23
23
|
create(context) {
|
|
24
24
|
const isRootCypress = (node) => {
|
|
25
25
|
if (
|
|
26
|
-
node.type !== 'CallExpression'
|
|
27
|
-
node.callee.type !== 'MemberExpression'
|
|
26
|
+
node.type !== 'CallExpression'
|
|
27
|
+
|| node.callee.type !== 'MemberExpression'
|
|
28
28
|
) {
|
|
29
|
-
return false
|
|
29
|
+
return false
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
if (
|
|
33
|
-
node.callee.object.type === 'Identifier'
|
|
34
|
-
node.callee.object.name === 'cy'
|
|
33
|
+
node.callee.object.type === 'Identifier'
|
|
34
|
+
&& node.callee.object.name === 'cy'
|
|
35
35
|
) {
|
|
36
|
-
return true
|
|
36
|
+
return true
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
return isRootCypress(node.callee.object)
|
|
40
|
-
}
|
|
39
|
+
return isRootCypress(node.callee.object)
|
|
40
|
+
}
|
|
41
41
|
|
|
42
42
|
const hasChainedGet = (node) => {
|
|
43
43
|
// Check if this node is a get() call
|
|
44
|
-
const isGetCall
|
|
45
|
-
node.callee
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
44
|
+
const isGetCall
|
|
45
|
+
= node.callee
|
|
46
|
+
&& node.callee.type === 'MemberExpression'
|
|
47
|
+
&& node.callee.property
|
|
48
|
+
&& node.callee.property.type === 'Identifier'
|
|
49
|
+
&& node.callee.property.name === 'get'
|
|
50
50
|
|
|
51
51
|
if (!isGetCall) {
|
|
52
|
-
return false
|
|
52
|
+
return false
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
const obj = node.callee.object
|
|
55
|
+
const obj = node.callee.object
|
|
56
56
|
|
|
57
57
|
if (obj.type === 'CallExpression') {
|
|
58
|
-
const objCallee = obj.callee
|
|
58
|
+
const objCallee = obj.callee
|
|
59
59
|
|
|
60
60
|
if (
|
|
61
|
-
objCallee
|
|
62
|
-
objCallee.type === 'MemberExpression'
|
|
63
|
-
objCallee.property
|
|
64
|
-
objCallee.property.type === 'Identifier'
|
|
65
|
-
objCallee.property.name === 'get'
|
|
61
|
+
objCallee
|
|
62
|
+
&& objCallee.type === 'MemberExpression'
|
|
63
|
+
&& objCallee.property
|
|
64
|
+
&& objCallee.property.type === 'Identifier'
|
|
65
|
+
&& objCallee.property.name === 'get'
|
|
66
66
|
) {
|
|
67
|
-
return true
|
|
67
|
+
return true
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
return hasChainedGet(obj)
|
|
70
|
+
return hasChainedGet(obj)
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
return false
|
|
74
|
-
}
|
|
73
|
+
return false
|
|
74
|
+
}
|
|
75
75
|
|
|
76
76
|
return {
|
|
77
77
|
CallExpression(node) {
|
|
@@ -79,9 +79,9 @@ module.exports = {
|
|
|
79
79
|
context.report({
|
|
80
80
|
node,
|
|
81
81
|
messageId: 'unexpected',
|
|
82
|
-
})
|
|
82
|
+
})
|
|
83
83
|
}
|
|
84
84
|
},
|
|
85
|
-
}
|
|
85
|
+
}
|
|
86
86
|
},
|
|
87
|
-
}
|
|
87
|
+
}
|
package/lib/rules/no-debug.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
// ------------------------------------------------------------------------------
|
|
4
4
|
// Rule Definition
|
|
5
|
-
|
|
5
|
+
// ------------------------------------------------------------------------------
|
|
6
6
|
|
|
7
7
|
module.exports = {
|
|
8
8
|
meta: {
|
|
@@ -20,37 +20,36 @@ module.exports = {
|
|
|
20
20
|
},
|
|
21
21
|
},
|
|
22
22
|
|
|
23
|
-
create
|
|
24
|
-
|
|
23
|
+
create(context) {
|
|
25
24
|
// variables should be defined here
|
|
26
25
|
|
|
27
|
-
|
|
26
|
+
// ----------------------------------------------------------------------
|
|
28
27
|
// Helpers
|
|
29
|
-
|
|
30
|
-
function isCallingDebug
|
|
31
|
-
return node.callee
|
|
32
|
-
node.callee.property
|
|
33
|
-
node.callee.property.type === 'Identifier'
|
|
34
|
-
node.callee.property.name === 'debug'
|
|
28
|
+
// ----------------------------------------------------------------------
|
|
29
|
+
function isCallingDebug(node) {
|
|
30
|
+
return node.callee
|
|
31
|
+
&& node.callee.property
|
|
32
|
+
&& node.callee.property.type === 'Identifier'
|
|
33
|
+
&& node.callee.property.name === 'debug'
|
|
35
34
|
}
|
|
36
35
|
|
|
37
|
-
function isCypressCall
|
|
36
|
+
function isCypressCall(node) {
|
|
38
37
|
if (!node.callee || node.callee.type !== 'MemberExpression') {
|
|
39
|
-
return false
|
|
38
|
+
return false
|
|
40
39
|
}
|
|
41
40
|
if (node.callee.object.type === 'Identifier' && node.callee.object.name === 'cy') {
|
|
42
|
-
return true
|
|
41
|
+
return true
|
|
43
42
|
}
|
|
44
|
-
return isCypressCall(node.callee.object)
|
|
43
|
+
return isCypressCall(node.callee.object)
|
|
45
44
|
}
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
|
|
46
|
+
// ----------------------------------------------------------------------
|
|
48
47
|
// Public
|
|
49
|
-
|
|
48
|
+
// ----------------------------------------------------------------------
|
|
50
49
|
|
|
51
50
|
return {
|
|
52
51
|
|
|
53
|
-
CallExpression
|
|
52
|
+
CallExpression(node) {
|
|
54
53
|
if (isCypressCall(node) && isCallingDebug(node)) {
|
|
55
54
|
context.report({ node, messageId: 'unexpected' })
|
|
56
55
|
}
|
package/lib/rules/no-force.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
// ------------------------------------------------------------------------------
|
|
4
4
|
// Rule Definition
|
|
5
|
-
|
|
5
|
+
// ------------------------------------------------------------------------------
|
|
6
6
|
|
|
7
7
|
module.exports = {
|
|
8
8
|
meta: {
|
|
@@ -20,39 +20,36 @@ module.exports = {
|
|
|
20
20
|
},
|
|
21
21
|
},
|
|
22
22
|
|
|
23
|
-
create
|
|
24
|
-
|
|
23
|
+
create(context) {
|
|
25
24
|
// variables should be defined here
|
|
26
25
|
|
|
27
|
-
|
|
26
|
+
// ----------------------------------------------------------------------
|
|
28
27
|
// Helpers
|
|
29
|
-
|
|
30
|
-
function isCallingClickOrType
|
|
28
|
+
// ----------------------------------------------------------------------
|
|
29
|
+
function isCallingClickOrType(node) {
|
|
31
30
|
const allowedMethods = ['click', 'dblclick', 'type', 'trigger', 'check', 'rightclick', 'focus', 'select']
|
|
32
31
|
|
|
33
|
-
return node.property && node.property.type === 'Identifier'
|
|
34
|
-
|
|
32
|
+
return node.property && node.property.type === 'Identifier'
|
|
33
|
+
&& allowedMethods.includes(node.property.name)
|
|
35
34
|
}
|
|
36
35
|
|
|
37
|
-
function isCypressCall
|
|
38
|
-
return node.callee.type === 'MemberExpression'
|
|
39
|
-
node.callee.object.type === 'Identifier'
|
|
40
|
-
node.callee.object.name === 'cy'
|
|
36
|
+
function isCypressCall(node) {
|
|
37
|
+
return node.callee.type === 'MemberExpression'
|
|
38
|
+
&& node.callee.object.type === 'Identifier'
|
|
39
|
+
&& node.callee.object.name === 'cy'
|
|
41
40
|
}
|
|
42
41
|
|
|
43
|
-
function hasOptionForce
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
})
|
|
42
|
+
function hasOptionForce(node) {
|
|
43
|
+
return node.arguments && node.arguments.length
|
|
44
|
+
&& node.arguments.some((arg) => {
|
|
45
|
+
return arg.type === 'ObjectExpression' && arg.properties.some((propNode) => propNode.key && propNode.key.name === 'force')
|
|
46
|
+
})
|
|
49
47
|
}
|
|
50
48
|
|
|
51
|
-
function deepCheck
|
|
49
|
+
function deepCheck(node, checkFunc) {
|
|
52
50
|
let currentNode = node
|
|
53
51
|
|
|
54
52
|
while (currentNode.parent) {
|
|
55
|
-
|
|
56
53
|
if (checkFunc(currentNode.parent)) {
|
|
57
54
|
return true
|
|
58
55
|
}
|
|
@@ -63,13 +60,13 @@ module.exports = {
|
|
|
63
60
|
return false
|
|
64
61
|
}
|
|
65
62
|
|
|
66
|
-
|
|
63
|
+
// ----------------------------------------------------------------------
|
|
67
64
|
// Public
|
|
68
|
-
|
|
65
|
+
// ----------------------------------------------------------------------
|
|
69
66
|
|
|
70
67
|
return {
|
|
71
68
|
|
|
72
|
-
CallExpression
|
|
69
|
+
CallExpression(node) {
|
|
73
70
|
if (isCypressCall(node) && deepCheck(node, isCallingClickOrType) && deepCheck(node, hasOptionForce)) {
|
|
74
71
|
context.report({ node, messageId: 'unexpected' })
|
|
75
72
|
}
|
package/lib/rules/no-pause.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
// ------------------------------------------------------------------------------
|
|
4
4
|
// Rule Definition
|
|
5
|
-
|
|
5
|
+
// ------------------------------------------------------------------------------
|
|
6
6
|
|
|
7
7
|
module.exports = {
|
|
8
8
|
meta: {
|
|
@@ -20,37 +20,36 @@ module.exports = {
|
|
|
20
20
|
},
|
|
21
21
|
},
|
|
22
22
|
|
|
23
|
-
create
|
|
24
|
-
|
|
23
|
+
create(context) {
|
|
25
24
|
// variables should be defined here
|
|
26
25
|
|
|
27
|
-
|
|
26
|
+
// ----------------------------------------------------------------------
|
|
28
27
|
// Helpers
|
|
29
|
-
|
|
30
|
-
function isCallingPause
|
|
31
|
-
return node.callee
|
|
32
|
-
node.callee.property
|
|
33
|
-
node.callee.property.type === 'Identifier'
|
|
34
|
-
node.callee.property.name === 'pause'
|
|
28
|
+
// ----------------------------------------------------------------------
|
|
29
|
+
function isCallingPause(node) {
|
|
30
|
+
return node.callee
|
|
31
|
+
&& node.callee.property
|
|
32
|
+
&& node.callee.property.type === 'Identifier'
|
|
33
|
+
&& node.callee.property.name === 'pause'
|
|
35
34
|
}
|
|
36
35
|
|
|
37
|
-
function isCypressCall
|
|
36
|
+
function isCypressCall(node) {
|
|
38
37
|
if (!node.callee || node.callee.type !== 'MemberExpression') {
|
|
39
|
-
return false
|
|
38
|
+
return false
|
|
40
39
|
}
|
|
41
40
|
if (node.callee.object.type === 'Identifier' && node.callee.object.name === 'cy') {
|
|
42
|
-
return true
|
|
41
|
+
return true
|
|
43
42
|
}
|
|
44
|
-
return isCypressCall(node.callee.object)
|
|
43
|
+
return isCypressCall(node.callee.object)
|
|
45
44
|
}
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
|
|
46
|
+
// ----------------------------------------------------------------------
|
|
48
47
|
// Public
|
|
49
|
-
|
|
48
|
+
// ----------------------------------------------------------------------
|
|
50
49
|
|
|
51
50
|
return {
|
|
52
51
|
|
|
53
|
-
CallExpression
|
|
52
|
+
CallExpression(node) {
|
|
54
53
|
if (isCypressCall(node) && isCallingPause(node)) {
|
|
55
54
|
context.report({ node, messageId: 'unexpected' })
|
|
56
55
|
}
|
|
@@ -14,11 +14,11 @@ module.exports = {
|
|
|
14
14
|
unexpected: 'Do not wait for arbitrary time periods',
|
|
15
15
|
},
|
|
16
16
|
},
|
|
17
|
-
create
|
|
17
|
+
create(context) {
|
|
18
18
|
const sourceCode = context.sourceCode ?? context.getSourceCode()
|
|
19
19
|
|
|
20
20
|
return {
|
|
21
|
-
CallExpression
|
|
21
|
+
CallExpression(node) {
|
|
22
22
|
if (isCallingCyWait(node)) {
|
|
23
23
|
const scope = sourceCode.getScope
|
|
24
24
|
? sourceCode.getScope(node)
|
|
@@ -33,7 +33,7 @@ module.exports = {
|
|
|
33
33
|
},
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
function nodeIsCalledByCy
|
|
36
|
+
function nodeIsCalledByCy(node) {
|
|
37
37
|
if (node.type === 'Identifier' && node.name === 'cy') return true
|
|
38
38
|
|
|
39
39
|
if (typeof node.callee === 'undefined' || typeof node.callee.object === 'undefined') {
|
|
@@ -43,20 +43,20 @@ function nodeIsCalledByCy (node) {
|
|
|
43
43
|
return nodeIsCalledByCy(node.callee.object)
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
function isCallingCyWait
|
|
47
|
-
return node.callee.type === 'MemberExpression'
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
46
|
+
function isCallingCyWait(node) {
|
|
47
|
+
return node.callee.type === 'MemberExpression'
|
|
48
|
+
&& nodeIsCalledByCy(node)
|
|
49
|
+
&& node.callee.property.type === 'Identifier'
|
|
50
|
+
&& node.callee.property.name === 'wait'
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
function isNumberArgument
|
|
54
|
-
return node.arguments.length > 0
|
|
55
|
-
|
|
56
|
-
|
|
53
|
+
function isNumberArgument(node) {
|
|
54
|
+
return node.arguments.length > 0
|
|
55
|
+
&& node.arguments[0].type === 'Literal'
|
|
56
|
+
&& typeof (node.arguments[0].value) === 'number'
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
function isIdentifierNumberConstArgument
|
|
59
|
+
function isIdentifierNumberConstArgument(node, scope) {
|
|
60
60
|
if (node.arguments.length === 0) return false
|
|
61
61
|
|
|
62
62
|
if (node.arguments[0].type !== 'Identifier') return false
|
package/lib/rules/no-xpath.js
CHANGED
|
@@ -6,7 +6,7 @@ module.exports = {
|
|
|
6
6
|
docs: {
|
|
7
7
|
description: 'disallow using `cy.xpath()` calls',
|
|
8
8
|
recommended: false,
|
|
9
|
-
url: 'https://github.com/cypress-io/eslint-plugin-cypress/blob/master/docs/rules/no-xpath.md'
|
|
9
|
+
url: 'https://github.com/cypress-io/eslint-plugin-cypress/blob/master/docs/rules/no-xpath.md',
|
|
10
10
|
},
|
|
11
11
|
fixable: null, // Or `code` or `whitespace`
|
|
12
12
|
schema: [], // Add a schema if the rule has options
|
|
@@ -15,21 +15,21 @@ module.exports = {
|
|
|
15
15
|
},
|
|
16
16
|
},
|
|
17
17
|
|
|
18
|
-
create
|
|
18
|
+
create(context) {
|
|
19
19
|
return {
|
|
20
|
-
CallExpression
|
|
20
|
+
CallExpression(node) {
|
|
21
21
|
if (isCallingCyXpath(node)) {
|
|
22
22
|
context.report({ node, messageId: 'unexpected' })
|
|
23
23
|
}
|
|
24
24
|
},
|
|
25
25
|
}
|
|
26
26
|
},
|
|
27
|
-
}
|
|
27
|
+
}
|
|
28
28
|
|
|
29
|
-
function isCallingCyXpath
|
|
30
|
-
return node.callee.type === 'MemberExpression'
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
29
|
+
function isCallingCyXpath(node) {
|
|
30
|
+
return node.callee.type === 'MemberExpression'
|
|
31
|
+
&& node.callee.object.type === 'Identifier'
|
|
32
|
+
&& node.callee.object.name === 'cy'
|
|
33
|
+
&& node.callee.property.type === 'Identifier'
|
|
34
|
+
&& node.callee.property.name === 'xpath'
|
|
35
35
|
}
|
|
@@ -15,9 +15,9 @@ module.exports = {
|
|
|
15
15
|
},
|
|
16
16
|
},
|
|
17
17
|
|
|
18
|
-
create
|
|
18
|
+
create(context) {
|
|
19
19
|
return {
|
|
20
|
-
CallExpression
|
|
20
|
+
CallExpression(node) {
|
|
21
21
|
if (isCallingCyGet(node) && !isDataArgument(node)) {
|
|
22
22
|
context.report({ node, messageId: 'unexpected' })
|
|
23
23
|
}
|
|
@@ -26,23 +26,23 @@ module.exports = {
|
|
|
26
26
|
},
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
function isCallingCyGet
|
|
30
|
-
return node.callee.type === 'MemberExpression'
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
29
|
+
function isCallingCyGet(node) {
|
|
30
|
+
return node.callee.type === 'MemberExpression'
|
|
31
|
+
&& node.callee.object.type === 'Identifier'
|
|
32
|
+
&& node.callee.object.name === 'cy'
|
|
33
|
+
&& node.callee.property.type === 'Identifier'
|
|
34
|
+
&& node.callee.property.name === 'get'
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
function isDataArgument
|
|
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)))
|
|
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
42
|
)
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
function isAliasOrDataSelector
|
|
45
|
+
function isAliasOrDataSelector(selector) {
|
|
46
46
|
return ['[data-', '@'].some(function (validValue) {
|
|
47
47
|
return selector.startsWith(validValue)
|
|
48
48
|
})
|
|
@@ -82,15 +82,15 @@ module.exports = {
|
|
|
82
82
|
'It is unsafe to chain further commands that rely on the subject after this command. It is best to split the chain, chaining again from `cy.` in a next command line.',
|
|
83
83
|
},
|
|
84
84
|
},
|
|
85
|
-
create
|
|
85
|
+
create(context) {
|
|
86
86
|
const { methods } = getDefaultOptions(context)
|
|
87
87
|
|
|
88
88
|
return {
|
|
89
|
-
CallExpression
|
|
89
|
+
CallExpression(node) {
|
|
90
90
|
if (
|
|
91
|
-
isRootCypress(node)
|
|
92
|
-
isActionUnsafeToChain(node, methods)
|
|
93
|
-
node.parent.type === 'MemberExpression'
|
|
91
|
+
isRootCypress(node)
|
|
92
|
+
&& isActionUnsafeToChain(node, methods)
|
|
93
|
+
&& node.parent.type === 'MemberExpression'
|
|
94
94
|
) {
|
|
95
95
|
context.report({
|
|
96
96
|
node,
|
|
@@ -108,15 +108,15 @@ module.exports = {
|
|
|
108
108
|
*/
|
|
109
109
|
const isRootCypress = (node) => {
|
|
110
110
|
if (
|
|
111
|
-
node.type !== 'CallExpression'
|
|
112
|
-
node.callee.type !== 'MemberExpression'
|
|
111
|
+
node.type !== 'CallExpression'
|
|
112
|
+
|| node.callee.type !== 'MemberExpression'
|
|
113
113
|
) {
|
|
114
114
|
return false
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
if (
|
|
118
|
-
node.callee.object.type === 'Identifier'
|
|
119
|
-
node.callee.object.name === 'cy'
|
|
118
|
+
node.callee.object.type === 'Identifier'
|
|
119
|
+
&& node.callee.object.name === 'cy'
|
|
120
120
|
) {
|
|
121
121
|
return true
|
|
122
122
|
}
|
|
@@ -135,9 +135,9 @@ const isActionUnsafeToChain = (node, additionalMethods = []) => {
|
|
|
135
135
|
].join('|'))
|
|
136
136
|
|
|
137
137
|
return (
|
|
138
|
-
node.callee
|
|
139
|
-
node.callee.property
|
|
140
|
-
node.callee.property.type === 'Identifier'
|
|
141
|
-
unsafeActionsRegex.test(node.callee.property.name)
|
|
138
|
+
node.callee
|
|
139
|
+
&& node.callee.property
|
|
140
|
+
&& node.callee.property.type === 'Identifier'
|
|
141
|
+
&& unsafeActionsRegex.test(node.callee.property.name)
|
|
142
142
|
)
|
|
143
143
|
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-cypress",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.1",
|
|
4
4
|
"description": "An ESLint plugin for projects using Cypress",
|
|
5
|
-
"main": "
|
|
5
|
+
"main": "./lib/flat.js",
|
|
6
6
|
"exports": {
|
|
7
|
-
".": "./
|
|
7
|
+
".": "./lib/flat.js",
|
|
8
8
|
"./flat": "./lib/flat.js"
|
|
9
9
|
},
|
|
10
10
|
"author": "Cypress-io",
|
|
@@ -26,24 +26,22 @@
|
|
|
26
26
|
"eslint": ">=9"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"globals": "^
|
|
29
|
+
"globals": "^16.2.0"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"eslint": "^
|
|
32
|
+
"@stylistic/eslint-plugin": "^4.4.0",
|
|
33
|
+
"eslint": "^9.27.0",
|
|
33
34
|
"eslint-plugin-eslint-plugin": "^6.4.0",
|
|
34
|
-
"eslint-plugin-mocha": "^
|
|
35
|
+
"eslint-plugin-mocha": "^11.1.0",
|
|
35
36
|
"husky": "^9.1.7",
|
|
36
|
-
"
|
|
37
|
-
"
|
|
37
|
+
"semantic-release": "24.2.5",
|
|
38
|
+
"vitest": "^3.1.4"
|
|
38
39
|
},
|
|
39
40
|
"scripts": {
|
|
40
|
-
"lint": "eslint
|
|
41
|
-
"lint-fix": "
|
|
41
|
+
"lint": "eslint",
|
|
42
|
+
"lint-fix": "eslint --fix",
|
|
42
43
|
"semantic-release": "semantic-release",
|
|
43
|
-
"
|
|
44
|
-
"test": "jest",
|
|
45
|
-
"test:legacy": "jest --config jest.config-legacy.js",
|
|
46
|
-
"test-watch": "jest --watchAll",
|
|
44
|
+
"test": "vitest run",
|
|
47
45
|
"prepare": "husky"
|
|
48
46
|
}
|
|
49
47
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// eslint-plugin-cypress/flat is deprecated and is identical to
|
|
2
|
+
// eslint-plugin-cypress
|
|
3
|
+
import pluginCypress from 'eslint-plugin-cypress/flat'
|
|
4
|
+
export default [
|
|
5
|
+
pluginCypress.configs.recommended,
|
|
6
|
+
{
|
|
7
|
+
rules: {
|
|
8
|
+
'cypress/no-unnecessary-waiting': 'off'
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
]
|