eslint-plugin-cypress 2.14.0 → 2.15.2

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.
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env sh
2
+ . "$(dirname -- "$0")/_/husky.sh"
3
+
4
+ npm run lint
package/.node-version ADDED
@@ -0,0 +1 @@
1
+ 16.15.0
package/.nvmrc ADDED
@@ -0,0 +1 @@
1
+ 16.15.0
package/README.md CHANGED
@@ -36,6 +36,7 @@ You can add rules:
36
36
  "cypress/assertion-before-screenshot": "warn",
37
37
  "cypress/no-force": "warn",
38
38
  "cypress/no-async-tests": "error",
39
+ "cypress/no-async-before": "error",
39
40
  "cypress/no-pause": "error"
40
41
  }
41
42
  }
package/circle.yml CHANGED
@@ -27,7 +27,7 @@ jobs:
27
27
  - checkout
28
28
  - run:
29
29
  name: Install dependencies
30
- command: npm install
30
+ command: npm ci
31
31
  - run:
32
32
  name: Lint code
33
33
  command: npm run lint
@@ -39,10 +39,13 @@ jobs:
39
39
  - checkout
40
40
  - run:
41
41
  name: Install dependencies
42
- command: npm install
42
+ command: npm ci
43
+ - run:
44
+ name: Install ESLint 4
45
+ command: npm install eslint@4
43
46
  - run:
44
47
  name: Test ESLint 4
45
- command: npm run test:v4
48
+ command: npm test
46
49
 
47
50
  test-v5:
48
51
  docker:
@@ -51,10 +54,13 @@ jobs:
51
54
  - checkout
52
55
  - run:
53
56
  name: Install dependencies
54
- command: npm install
57
+ command: npm ci
58
+ - run:
59
+ name: Install ESLint 5
60
+ command: npm install eslint@5
55
61
  - run:
56
62
  name: Test ESLint 5
57
- command: npm run test
63
+ command: npm test
58
64
 
59
65
  test-v6:
60
66
  docker:
@@ -63,10 +69,13 @@ jobs:
63
69
  - checkout
64
70
  - run:
65
71
  name: Install dependencies
66
- command: npm install
72
+ command: npm ci
73
+ - run:
74
+ name: Install ESLint 6
75
+ command: npm install eslint@6
67
76
  - run:
68
77
  name: Test ESLint 6
69
- command: npm run test:v6
78
+ command: npm test
70
79
 
71
80
  release:
72
81
  docker:
@@ -75,7 +84,7 @@ jobs:
75
84
  - checkout
76
85
  - run:
77
86
  name: Install dependencies
78
- command: npm install
87
+ command: npm ci
79
88
  - run:
80
89
  name: Run semantic release
81
90
  command: npm run semantic-release
@@ -0,0 +1,52 @@
1
+ # Prevent using async/await in Cypress test cases (no-async-tests)
2
+
3
+ Cypress commands that return a promise may cause side effects in before/beforeEach hooks, possibly causing unexpected behavior.
4
+
5
+ ## Rule Details
6
+
7
+ This rule disallows using `async` `before` and `beforeEach` functions.
8
+
9
+ Examples of **incorrect** code for this rule:
10
+
11
+ ```js
12
+ describe('my feature', () => {
13
+ before('my test case', async () => {
14
+ await cy.get('.myClass')
15
+ // other operations
16
+ })
17
+ })
18
+ ```
19
+
20
+ ```js
21
+ describe('my feature', () => {
22
+ before('my test case', async () => {
23
+ cy
24
+ .get('.myClass')
25
+ .click()
26
+
27
+ await someAsyncFunction()
28
+ })
29
+ })
30
+ ```
31
+
32
+ Examples of **correct** code for this rule:
33
+
34
+ ```js
35
+ describe('my feature', () => {
36
+ before('my test case', () => {
37
+ cy.get('.myClass')
38
+ // other operations
39
+ })
40
+ })
41
+
42
+ ```
43
+
44
+ ## When Not To Use It
45
+
46
+ If there are genuine use-cases for using `async/await` in your before then you may not want to include this rule (or at least demote it to a warning).
47
+
48
+ ## Further Reading
49
+
50
+ - [Commands Are Asynchronous](https://docs.cypress.io/guides/core-concepts/introduction-to-cypress.html#Commands-Are-Asynchronous)
51
+ - [Commands Are Promises](https://docs.cypress.io/guides/core-concepts/introduction-to-cypress.html#Commands-Are-Promises)
52
+ - [Commands Are Not Promises](https://docs.cypress.io/guides/core-concepts/introduction-to-cypress.html#Commands-Are-Not-Promises)
@@ -0,0 +1,47 @@
1
+ 'use strict'
2
+
3
+ module.exports = {
4
+ meta: {
5
+ docs: {
6
+ description: 'Prevent using async/await in Cypress before methods',
7
+ category: 'Possible Errors',
8
+ recommended: true,
9
+ },
10
+ messages: {
11
+ unexpected: 'Avoid using async functions with Cypress before / beforeEach functions',
12
+ },
13
+ },
14
+
15
+ create (context) {
16
+ function isBeforeBlock (callExpressionNode) {
17
+ const { type, name } = callExpressionNode.callee
18
+
19
+ return type === 'Identifier'
20
+ && name === 'before' || name === 'beforeEach'
21
+ }
22
+
23
+ function isBeforeAsync (node) {
24
+ return node.arguments
25
+ && node.arguments.length >= 2
26
+ && node.arguments[1].async === true
27
+ }
28
+
29
+ return {
30
+ Identifier (node) {
31
+ if (node.name === 'cy' || node.name === 'Cypress') {
32
+ const ancestors = context.getAncestors()
33
+ const asyncTestBlocks = ancestors
34
+ .filter((n) => n.type === 'CallExpression')
35
+ .filter(isBeforeBlock)
36
+ .filter(isBeforeAsync)
37
+
38
+ if (asyncTestBlocks.length >= 1) {
39
+ asyncTestBlocks.forEach((node) => {
40
+ context.report({ node, messageId: 'unexpected' })
41
+ })
42
+ }
43
+ }
44
+ },
45
+ }
46
+ },
47
+ }
@@ -19,7 +19,7 @@ const unsafeToChainActions = [
19
19
  'check',
20
20
  'dblclick',
21
21
  'each',
22
- 'focus',
22
+ 'focus$',
23
23
  'rightclick',
24
24
  'screenshot',
25
25
  'scrollIntoView',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-cypress",
3
- "version": "2.14.0",
3
+ "version": "2.15.2",
4
4
  "description": "An ESLint plugin for projects using Cypress",
5
5
  "main": "index.js",
6
6
  "author": "Cypress-io",
@@ -27,22 +27,21 @@
27
27
  "devDependencies": {
28
28
  "@cypress/eslint-plugin-dev": "3.2.0",
29
29
  "@cypress/eslint-plugin-json": "3.2.1",
30
- "condition-circle": "2.0.2",
31
30
  "eslint": "^5.7.0",
32
- "husky": "^3.0.0",
31
+ "husky": "^8.0.3",
33
32
  "jest": "^24.8.0",
34
- "semantic-release": "15.13.18"
33
+ "semantic-release": "19.0.3"
35
34
  },
36
35
  "scripts": {
37
- "precommit": "npm run lint",
38
- "lint": "eslint '*.js' '**/**/*.js'",
36
+ "lint": "eslint \"*.js\" \"**/**/*.js\"",
39
37
  "lint-fix": "npm run lint -- --fix",
40
38
  "semantic-release": "semantic-release",
41
39
  "start": "yarn run test-watch",
42
40
  "test": "jest",
43
41
  "test:v4": "npm i eslint@4.x && npm run test",
44
42
  "test:v6": "npm i eslint@6.x && npm run test",
45
- "test-watch": "jest --watchAll"
43
+ "test-watch": "jest --watchAll",
44
+ "prepare": "husky install"
46
45
  },
47
46
  "jest": {
48
47
  "testMatch": [
@@ -0,0 +1,25 @@
1
+ 'use strict'
2
+
3
+ const rule = require('../../../lib/rules/no-async-before')
4
+ const RuleTester = require('eslint').RuleTester
5
+
6
+ const ruleTester = new RuleTester()
7
+
8
+ const errors = [{ messageId: 'unexpected' }]
9
+ // async functions are an ES2017 feature
10
+ const parserOptions = { ecmaVersion: 8 }
11
+
12
+ ruleTester.run('no-async-before', rule, {
13
+ valid: [
14
+ { code: 'before(\'a before case\', () => { cy.get(\'.someClass\'); })', parserOptions },
15
+ { code: 'before(\'a before case\', async () => { await somethingAsync(); })', parserOptions },
16
+ { code: 'async function nonTestFn () { return await somethingAsync(); }', parserOptions },
17
+ { code: 'const nonTestArrowFn = async () => { await somethingAsync(); }', parserOptions },
18
+ ],
19
+ invalid: [
20
+ { code: 'before(\'a test case\', async () => { cy.get(\'.someClass\'); })', parserOptions, errors },
21
+ { code: 'beforeEach(\'a test case\', async () => { cy.get(\'.someClass\'); })', parserOptions, errors },
22
+ { code: 'before(\'a test case\', async function () { cy.get(\'.someClass\'); })', parserOptions, errors },
23
+ { code: 'beforeEach(\'a test case\', async function () { cy.get(\'.someClass\'); })', parserOptions, errors },
24
+ ],
25
+ })
@@ -14,6 +14,10 @@ ruleTester.run('action-ends-chain', rule, {
14
14
  code: 'cy.get("new-todo").type("todo A{enter}"); cy.get("new-todo").type("todo B{enter}"); cy.get("new-todo").should("have.class", "active");',
15
15
  parserOptions,
16
16
  },
17
+ {
18
+ code: 'cy.focused().should("be.visible");',
19
+ parserOptions,
20
+ },
17
21
  ],
18
22
 
19
23
  invalid: [
@@ -27,6 +31,11 @@ ruleTester.run('action-ends-chain', rule, {
27
31
  parserOptions,
28
32
  errors,
29
33
  },
34
+ {
35
+ code: 'cy.get("new-todo").focus().should("have.class", "active");',
36
+ parserOptions,
37
+ errors,
38
+ },
30
39
  {
31
40
  code: 'cy.get("new-todo").customType("todo A{enter}").customClick();',
32
41
  parserOptions,