eslint-plugin-cypress 5.1.0 → 5.2.0

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/CONTRIBUTING.md CHANGED
@@ -4,45 +4,47 @@ Thanks for taking the time to contribute! :smile:
4
4
 
5
5
  ## Preparation
6
6
 
7
- * Fork and clone this repository
8
- * Branch from the default `master` branch using a descriptive new branch name
9
- * Install dependencies with `npm ci`
7
+ - Fork and clone this repository
8
+ - Branch from the default `master` branch using a descriptive new branch name
9
+ - Install dependencies with `npm ci`
10
10
 
11
11
  ## Rule references
12
12
 
13
- * Refer to the [ESLint documentation](https://eslint.org/docs/latest/) and the [Custom Rules](https://eslint.org/docs/latest/extend/custom-rules) page
13
+ - Refer to the [ESLint documentation](https://eslint.org/docs/latest/) and the [Custom Rules](https://eslint.org/docs/latest/extend/custom-rules) page
14
14
 
15
15
  ## New rule
16
16
 
17
17
  To add a new rule:
18
18
 
19
- * Follow the instructions in the ESLint [generator-eslint](https://www.npmjs.com/package/generator-eslint) documentation to install [Yeoman](https://www.npmjs.com/package/yo) and the generator
20
- * Run the new rule generator `yo eslint:rule` and answer the questions
19
+ - Follow the instructions in the ESLint [generator-eslint](https://www.npmjs.com/package/generator-eslint) documentation to install [Yeoman](https://www.npmjs.com/package/yo) and the generator
20
+ - Run the new rule generator `yo eslint:rule` and answer the questions
21
21
  - select "ESLint Plugin"
22
22
  - for "Type a short description of this rule" provide text which starts with one of "enforce", "require" or "disallow" (all lower case)
23
- * Yeoman creates three boilerplate files:
23
+ - Yeoman creates three boilerplate files:
24
24
  - `docs/rules/<rule-id>.md`
25
25
  - `lib/rules/<rule-id>.js`
26
26
  - `test/rules/<rule-id>.js`
27
- * Run `npm run lint-fix`
28
- * Address the linting errors by editing `lib/rules/<rule-id>.js`
27
+ - Run `npm run lint-fix`
28
+ - Address the linting errors by editing `lib/rules/<rule-id>.js`
29
29
  - Add a `meta.messages` property (see [MessageIds](https://eslint.org/docs/latest/extend/custom-rules#messageids))
30
30
  - Select the appropriate `meta.type` property using `problem`, `suggestion`, or `layout`
31
- * Complete the new rule by adding content to the three files previously created
32
- * Run `eslint-doc-generator` to generate automated documentation sections (see [Document generation](#document-generation) below)
33
- * Review documentation changes
34
- * Run `npm run lint`
35
- * Run `npm test` to run [Vitest](https://vitest.dev/)
36
- * Make sure all tests are passing
37
- * Add the rule to [flat.js](https://github.com/cypress-io/eslint-plugin-cypress/blob/master/lib/flat.js)
38
- * Create a git commit with a commit message similar to: `feat: add rule <description>` (see [commit message conventions](https://github.com/semantic-release/semantic-release#commit-message-format))
39
- * Create a PR from your branch
31
+ - Complete the new rule by adding content to the three files previously created
32
+ - Run `eslint-doc-generator` to generate automated documentation sections (see [Document generation](#document-generation) below)
33
+ - Review documentation changes
34
+ - Run `npm run lint`
35
+ - Run `npm run format`
36
+ - Run `npm test` to run [Vitest](https://vitest.dev/)
37
+ - Make sure all tests are passing
38
+ - Add the rule to [flat.js](https://github.com/cypress-io/eslint-plugin-cypress/blob/master/lib/flat.js)
39
+ - Create a git commit with a commit message similar to: `feat: add rule <description>` (see [commit message conventions](https://github.com/semantic-release/semantic-release#commit-message-format))
40
+ - Create a PR from your branch
40
41
 
41
42
  ## Document generation
42
43
 
43
44
  This plugin uses the ESLint [eslint-doc-generator](https://www.npmjs.com/package/eslint-doc-generator) to generate consistent documentation.
44
- * Install with `npm install eslint-doc-generator -g`
45
- * Run `eslint-doc-generator` in the root directory of the plugin
45
+
46
+ - Install with `npm install eslint-doc-generator -g`
47
+ - Run `eslint-doc-generator` in the root directory of the plugin
46
48
 
47
49
  ## Merging pull requests
48
50
 
@@ -65,7 +67,7 @@ This information is for Cypress.io Members or Collaborators who merge pull reque
65
67
  ```
66
68
 
67
69
  1. New versions of this module will be released automatically by the CI pipeline when any PR with a triggering commit message is merged to the `master` branch: see the `release` job of [circle.yml](circle.yml).
68
- This will create a new [GitHub release](https://github.com/cypress-io/eslint-plugin-cypress/releases) and publish it to [eslint-plugin-cypress](https://www.npmjs.com/package/eslint-plugin-cypress) on the [npm registry](https://docs.npmjs.com/about-the-public-npm-registry).
70
+ This will create a new [GitHub release](https://github.com/cypress-io/eslint-plugin-cypress/releases) and publish it to [eslint-plugin-cypress](https://www.npmjs.com/package/eslint-plugin-cypress) on the [npm registry](https://docs.npmjs.com/about-the-public-npm-registry).
69
71
  1. The module's CI is configured to use the [default Angular release rules](https://github.com/semantic-release/commit-analyzer/blob/master/lib/default-release-rules.js).
70
- This means that only `feat:`, `fix:` and `perf:` trigger a new release.
71
- Other Angular commit types listed in the [Angular commit message guidelines](https://github.com/angular/angular/blob/main/contributing-docs/commit-message-guidelines.md) can be used for documentation purposes, however they are ignored by the currently configured release process.
72
+ This means that only `feat:`, `fix:` and `perf:` trigger a new release.
73
+ Other Angular commit types listed in the [Angular commit message guidelines](https://github.com/angular/angular/blob/main/contributing-docs/commit-message-guidelines.md) can be used for documentation purposes, however they are ignored by the currently configured release process.
package/README.md CHANGED
@@ -11,7 +11,9 @@ Prerequisites: [ESLint](https://www.npmjs.com/package/eslint) `v9`. Lower versio
11
11
  ```sh
12
12
  npm install eslint eslint-plugin-cypress --save-dev
13
13
  ```
14
+
14
15
  or
16
+
15
17
  ```sh
16
18
  yarn add eslint eslint-plugin-cypress --dev
17
19
  ```
@@ -36,15 +38,16 @@ import pluginCypress from 'eslint-plugin-cypress/flat' # deprecated
36
38
 
37
39
  There are two specific configurations available:
38
40
 
39
- | Configuration | Content |
40
- | --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
41
+ | Configuration | Content |
42
+ | --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
41
43
  | `configs.globals` | defines globals `cy`, `Cypress`, `expect`, `assert` and `chai` used in Cypress test specs as well as `globals.browser` and `globals.mocha` from [globals](https://www.npmjs.com/package/globals). There are no default rules enabled in this configuration. |
42
- | `configs.recommended` | enables [recommended Rules](#rules). It includes also `configs.global` (see above). |
44
+ | `configs.recommended` | enables [recommended Rules](#rules). It includes also `configs.global` (see above). |
43
45
 
44
46
  ## Rules
45
47
 
46
48
  These rules enforce some of the [best practices recommended for using Cypress](https://on.cypress.io/best-practices).
47
49
 
50
+ <!-- prettier-ignore-start -->
48
51
  <!-- begin auto-generated rules list -->
49
52
 
50
53
  💼 Configurations enabled in.\
@@ -66,45 +69,55 @@ These rules enforce some of the [best practices recommended for using Cypress](h
66
69
  | [unsafe-to-chain-command](docs/rules/unsafe-to-chain-command.md) | disallow actions within chains | ✅ |
67
70
 
68
71
  <!-- end auto-generated rules list -->
72
+ <!-- prettier-ignore-end -->
69
73
 
70
74
  ## Usage examples
71
75
 
72
76
  In the following sections, different examples of possible configuration file contents are given, together with some brief explanations. Adapt these examples according to your needs.
73
77
 
78
+ The examples use the `defineConfig()` helper, introduced with ESLint [9.22.0](https://eslint.org/blog/2025/03/eslint-v9.22.0-released/). Refer to the blog article [Evolving flat config with extends](https://eslint.org/blog/2025/03/flat-config-extends-define-config-global-ignores/) for background information. If you are using ESLint `<9.22.0`, import `defineConfig` from [@eslint/config-helpers](https://www.npmjs.com/package/@eslint/config-helpers) instead of from `eslint/config`.
79
+
74
80
  ### Cypress
75
81
 
76
82
  All rules are available by importing from `eslint-plugin-cypress` and can be individually activated.
83
+
77
84
  - [cypress/unsafe-to-chain-command](https://github.com/cypress-io/eslint-plugin-cypress/blob/master/docs/rules/unsafe-to-chain-command.md) is activated and set to `error`
78
85
 
79
86
  ```js
87
+ import { defineConfig } from 'eslint/config'
80
88
  import pluginCypress from 'eslint-plugin-cypress'
81
- export default [
89
+ export default defineConfig([
82
90
  {
83
91
  plugins: {
84
- cypress: pluginCypress
92
+ cypress: pluginCypress,
85
93
  },
86
94
  rules: {
87
- 'cypress/unsafe-to-chain-command': 'error'
88
- }
89
- }
90
- ]
95
+ 'cypress/unsafe-to-chain-command': 'error',
96
+ },
97
+ },
98
+ ])
91
99
  ```
92
100
 
93
101
  ### Cypress recommended
94
102
 
95
103
  The `eslint-plugin-cypress` [recommended rules](#rules) `configs.recommended` are activated, except for
104
+
96
105
  - [cypress/no-unnecessary-waiting](https://github.com/cypress-io/eslint-plugin-cypress/blob/master/docs/rules/no-unnecessary-waiting.md) which is set to `off`
97
106
 
98
107
  ```js
108
+ import { defineConfig } from 'eslint/config'
99
109
  import pluginCypress from 'eslint-plugin-cypress'
100
- export default [
101
- pluginCypress.configs.recommended,
110
+ export default defineConfig([
102
111
  {
112
+ files: ['cypress/**/*.js'],
113
+ extends: [
114
+ pluginCypress.configs.recommended,
115
+ ],
103
116
  rules: {
104
- 'cypress/no-unnecessary-waiting': 'off'
105
- }
106
- }
107
- ]
117
+ 'cypress/no-unnecessary-waiting': 'off',
118
+ },
119
+ },
120
+ ])
108
121
  ```
109
122
 
110
123
  ### Cypress globals
@@ -112,10 +125,16 @@ export default [
112
125
  The `configs.globals` are activated.
113
126
 
114
127
  ```js
128
+ import { defineConfig } from 'eslint/config'
115
129
  import pluginCypress from 'eslint-plugin-cypress'
116
- export default [
117
- pluginCypress.configs.globals
118
- ]
130
+ export default defineConfig([
131
+ {
132
+ files: ['cypress/**/*.js'],
133
+ extends: [
134
+ pluginCypress.configs.globals,
135
+ ],
136
+ },
137
+ ])
119
138
  ```
120
139
 
121
140
  ## Disable rules
@@ -174,6 +193,7 @@ During test spec development, [Mocha exclusive tests](https://mochajs.org/#exclu
174
193
  [eslint-plugin-mocha@^11](https://www.npmjs.com/package/eslint-plugin-mocha) is added to the example [Cypress recommended](#cypress-recommended). This version of the plugin supports only flat file configurations with the option `configs.recommended`.
175
194
 
176
195
  The settings for individual `mocha` rules from the `configs.recommended` option are changed.
196
+
177
197
  - [mocha/no-exclusive-tests](https://github.com/lo1tuma/eslint-plugin-mocha/blob/main/docs/rules/no-exclusive-tests.md) and [mocha/no-pending-tests](https://github.com/lo1tuma/eslint-plugin-mocha/blob/main/docs/rules/no-pending-tests.md) are set to `error` instead of `warn`
178
198
  - [mocha/no-mocha-arrows](https://github.com/lo1tuma/eslint-plugin-mocha/blob/main/docs/rules/no-mocha-arrows.md) is set to `off` instead of `error`
179
199
 
@@ -182,20 +202,24 @@ npm install eslint-plugin-mocha@^11 --save-dev
182
202
  ```
183
203
 
184
204
  ```js
205
+ import { defineConfig } from 'eslint/config'
185
206
  import pluginMocha from 'eslint-plugin-mocha'
186
207
  import pluginCypress from 'eslint-plugin-cypress'
187
- export default [
188
- pluginMocha.configs.recommended,
189
- pluginCypress.configs.recommended,
208
+ export default defineConfig([
190
209
  {
210
+ files: ['cypress/**/*.js'],
211
+ extends: [
212
+ pluginMocha.configs.recommended,
213
+ pluginCypress.configs.recommended,
214
+ ],
191
215
  rules: {
192
216
  'mocha/no-exclusive-tests': 'error',
193
217
  'mocha/no-pending-tests': 'error',
194
218
  'mocha/no-mocha-arrows': 'off',
195
- 'cypress/no-unnecessary-waiting': 'off'
196
- }
197
- }
198
- ]
219
+ 'cypress/no-unnecessary-waiting': 'off',
220
+ },
221
+ },
222
+ ])
199
223
  ```
200
224
 
201
225
  ### Cypress and Chai recommended
@@ -211,17 +235,21 @@ npm install eslint-plugin-chai-friendly@^1.0.1 --save-dev
211
235
  ```
212
236
 
213
237
  ```js
238
+ import { defineConfig } from 'eslint/config'
214
239
  import pluginCypress from 'eslint-plugin-cypress'
215
240
  import pluginChaiFriendly from 'eslint-plugin-chai-friendly'
216
- export default [
217
- pluginCypress.configs.recommended,
218
- pluginChaiFriendly.configs.recommendedFlat,
241
+ export default defineConfig([
219
242
  {
243
+ files: ['cypress/**/*.js'],
244
+ extends: [
245
+ pluginCypress.configs.recommended,
246
+ pluginChaiFriendly.configs.recommendedFlat,
247
+ ],
220
248
  rules: {
221
249
  'cypress/no-unnecessary-waiting': 'off',
222
250
  },
223
- }
224
- ]
251
+ },
252
+ ])
225
253
  ```
226
254
 
227
255
  ## Contributing
@@ -1,6 +1,7 @@
1
1
  # Require screenshots to be preceded by an assertion (`cypress/assertion-before-screenshot`)
2
2
 
3
3
  <!-- end auto-generated rule header -->
4
+
4
5
  If you take screenshots without assertions then you may get different screenshots depending on timing.
5
6
 
6
7
  For example, if clicking a button makes some network calls and upon success, renders something, then the screenshot may sometimes have the new render and sometimes not.
@@ -12,14 +13,14 @@ This rule checks there is an assertion making sure your application state is cor
12
13
  Examples of **incorrect** code for this rule:
13
14
 
14
15
  ```js
15
- cy.visit('myUrl');
16
- cy.screenshot();
16
+ cy.visit('myUrl')
17
+ cy.screenshot()
17
18
  ```
18
19
 
19
20
  Examples of **correct** code for this rule:
20
21
 
21
22
  ```js
22
- cy.visit('myUrl');
23
- cy.get('[data-test-id="my-element"]').should('be.visible');
24
- cy.screenshot();
23
+ cy.visit('myUrl')
24
+ cy.get('[data-test-id="my-element"]').should('be.visible')
25
+ cy.screenshot()
25
26
  ```
@@ -3,6 +3,7 @@
3
3
  💼 This rule is enabled in the ✅ `recommended` config.
4
4
 
5
5
  <!-- end auto-generated rule header -->
6
+
6
7
  ## Further Reading
7
8
 
8
9
  See [the Cypress Best Practices guide](https://on.cypress.io/best-practices#Assigning-Return-Values).
@@ -1,6 +1,7 @@
1
1
  # Disallow using `async`/`await` in Cypress `before` methods (`cypress/no-async-before`)
2
2
 
3
3
  <!-- end auto-generated rule header -->
4
+
4
5
  Cypress commands that return a promise may cause side effects in `before`/`beforeEach` hooks, possibly causing unexpected behavior.
5
6
 
6
7
  ## Rule Details
@@ -11,7 +12,7 @@ Examples of **incorrect** code for this rule:
11
12
 
12
13
  ```js
13
14
  describe('my feature', () => {
14
- before('my test case', async () => {
15
+ before('my test case', async () => {
15
16
  await cy.get('.myClass')
16
17
  // other operations
17
18
  })
@@ -20,10 +21,8 @@ describe('my feature', () => {
20
21
 
21
22
  ```js
22
23
  describe('my feature', () => {
23
- before('my test case', async () => {
24
- cy
25
- .get('.myClass')
26
- .click()
24
+ before('my test case', async () => {
25
+ cy.get('.myClass').click()
27
26
 
28
27
  await someAsyncFunction()
29
28
  })
@@ -34,7 +33,7 @@ Examples of **correct** code for this rule:
34
33
 
35
34
  ```js
36
35
  describe('my feature', () => {
37
- before('my test case', () => {
36
+ before('my test case', () => {
38
37
  cy.get('.myClass')
39
38
  // other operations
40
39
  })
@@ -47,5 +46,5 @@ If there are genuine use-cases for using `async/await` in your `before` hooks th
47
46
 
48
47
  ## Further Reading
49
48
 
50
- - [Mixing Async and Sync code](https://on.cypress.io/guides/core-concepts/introduction-to-cypress#Mixing-Async-and-Sync-code)
51
- - [Commands Are Asynchronous](https://on.cypress.io/guides/core-concepts/introduction-to-cypress.html#Commands-Are-Asynchronous)
49
+ - [Mixing Async and Sync code](https://on.cypress.io/app/core-concepts/introduction-to-cypress#Mixing-Async-and-Sync-code)
50
+ - [Commands Are Asynchronous](https://on.cypress.io/app/core-concepts/introduction-to-cypress.html#Commands-Are-Asynchronous)
@@ -3,7 +3,8 @@
3
3
  💼 This rule is enabled in the ✅ `recommended` config.
4
4
 
5
5
  <!-- end auto-generated rule header -->
6
- Cypress tests [that return a promise will error](https://docs.cypress.io/guides/references/error-messages.html#Cypress-detected-that-you-returned-a-promise-from-a-command-while-also-invoking-one-or-more-cy-commands-in-that-promise) and cannot run successfully.
6
+
7
+ Cypress tests [that return a promise will error](https://docs.cypress.io/app/references/error-messages.html#Cypress-detected-that-you-returned-a-promise-from-a-command-while-also-invoking-one-or-more-cy-commands-in-that-promise) and cannot run successfully.
7
8
  An `async` function returns a promise under the hood, so a test using an `async` function will also error.
8
9
 
9
10
  ## Rule Details
@@ -14,7 +15,7 @@ Examples of **incorrect** code for this rule:
14
15
 
15
16
  ```js
16
17
  describe('my feature', () => {
17
- it('my test case', async () => {
18
+ it('my test case', async () => {
18
19
  await cy.get('.myClass')
19
20
  // other operations
20
21
  })
@@ -23,10 +24,8 @@ describe('my feature', () => {
23
24
 
24
25
  ```js
25
26
  describe('my feature', () => {
26
- it('my test case', async () => {
27
- cy
28
- .get('.myClass')
29
- .click()
27
+ it('my test case', async () => {
28
+ cy.get('.myClass').click()
30
29
 
31
30
  await someAsyncFunction()
32
31
  })
@@ -37,7 +36,7 @@ Examples of **correct** code for this rule:
37
36
 
38
37
  ```js
39
38
  describe('my feature', () => {
40
- it('my test case', () => {
39
+ it('my test case', () => {
41
40
  cy.get('.myClass')
42
41
  // other operations
43
42
  })
@@ -50,5 +49,5 @@ If there are genuine use-cases for using `async/await` in your test cases then y
50
49
 
51
50
  ## Further Reading
52
51
 
53
- - [Mixing Async and Sync code](https://on.cypress.io/guides/core-concepts/introduction-to-cypress#Mixing-Async-and-Sync-code)
54
- - [Commands Are Asynchronous](https://on.cypress.io/guides/core-concepts/introduction-to-cypress.html#Commands-Are-Asynchronous)
52
+ - [Mixing Async and Sync code](https://on.cypress.io/app/core-concepts/introduction-to-cypress#Mixing-Async-and-Sync-code)
53
+ - [Commands Are Asynchronous](https://on.cypress.io/app/core-concepts/introduction-to-cypress.html#Commands-Are-Asynchronous)
@@ -1,6 +1,7 @@
1
1
  # Disallow chain of `cy.get()` calls (`cypress/no-chained-get`)
2
2
 
3
3
  <!-- end auto-generated rule header -->
4
+
4
5
  This rule disallows the usage of chained `.get()` calls as `cy.get()` always starts its search from the cy.root element.
5
6
 
6
7
  ## Rule Details
@@ -14,6 +15,5 @@ cy.get('parent').get('child')
14
15
  Examples of **correct** code for this rule:
15
16
 
16
17
  ```js
17
- cy.get('parent')
18
- .find('child')
18
+ cy.get('parent').find('child')
19
19
  ```
@@ -1,6 +1,7 @@
1
1
  # Disallow using `cy.debug()` calls (`cypress/no-debug`)
2
2
 
3
3
  <!-- end auto-generated rule header -->
4
+
4
5
  It is recommended to remove any [cy.debug](https://on.cypress.io/debug) commands before committing specs to avoid other developers getting unexpected results.
5
6
 
6
7
  ## Rule Details
@@ -8,8 +9,8 @@ It is recommended to remove any [cy.debug](https://on.cypress.io/debug) commands
8
9
  Examples of **incorrect** code for this rule:
9
10
 
10
11
  ```js
11
- cy.debug();
12
- cy.get('selector').debug();
12
+ cy.debug()
13
+ cy.get('selector').debug()
13
14
  ```
14
15
 
15
16
  Examples of **correct** code for this rule:
@@ -1,9 +1,10 @@
1
1
  # Disallow using `force: true` with action commands (`cypress/no-force`)
2
2
 
3
3
  <!-- end auto-generated rule header -->
4
+
4
5
  Using `force: true` on inputs appears to be confusing rather than helpful.
5
6
  It usually silences the actual problem instead of providing a way to overcome it.
6
- See [Cypress Core Concepts](https://docs.cypress.io/guides/core-concepts/interacting-with-elements.html#Forcing).
7
+ See [Cypress Core Concepts](https://docs.cypress.io/app/core-concepts/interacting-with-elements.html#Forcing).
7
8
 
8
9
  If enabling this rule, it's recommended to set the severity to `warn`.
9
10
 
@@ -18,26 +19,26 @@ and [`.trigger()`](https://on.cypress.io/trigger).
18
19
  Examples of **incorrect** code for this rule:
19
20
 
20
21
  ```js
21
- cy.get('button').click({force: true})
22
- cy.get('button').dblclick({force: true})
23
- cy.get('input').type('somth', {force: true})
24
- cy.get('div').find('.foo').find('.bar').trigger('change', {force: true})
25
- cy.get('input').trigger('click', {force: true})
26
- cy.get('input').rightclick({force: true})
27
- cy.get('input').check({force: true})
28
- cy.get('input').select({force: true})
29
- cy.get('input').focus({force: true})
22
+ cy.get('button').click({ force: true })
23
+ cy.get('button').dblclick({ force: true })
24
+ cy.get('input').type('somth', { force: true })
25
+ cy.get('div').find('.foo').find('.bar').trigger('change', { force: true })
26
+ cy.get('input').trigger('click', { force: true })
27
+ cy.get('input').rightclick({ force: true })
28
+ cy.get('input').check({ force: true })
29
+ cy.get('input').select({ force: true })
30
+ cy.get('input').focus({ force: true })
30
31
  ```
31
32
 
32
33
  Examples of **correct** code for this rule:
33
34
 
34
35
  ```js
35
36
  cy.get('button').click()
36
- cy.get('button').click({multiple: true})
37
+ cy.get('button').click({ multiple: true })
37
38
  cy.get('button').dblclick()
38
39
  cy.get('input').type('somth')
39
- cy.get('input').trigger('click', {anyoption: true})
40
- cy.get('input').rightclick({anyoption: true})
40
+ cy.get('input').trigger('click', { anyoption: true })
41
+ cy.get('input').rightclick({ anyoption: true })
41
42
  cy.get('input').check()
42
43
  cy.get('input').select()
43
44
  cy.get('input').focus()
@@ -1,6 +1,7 @@
1
1
  # Disallow using `cy.pause()` calls (`cypress/no-pause`)
2
2
 
3
3
  <!-- end auto-generated rule header -->
4
+
4
5
  It is recommended to remove any [cy.pause](https://on.cypress.io/pause) commands before committing specs to avoid other developers getting unexpected results.
5
6
 
6
7
  ## Rule Details
@@ -8,8 +9,8 @@ It is recommended to remove any [cy.pause](https://on.cypress.io/pause) commands
8
9
  Examples of **incorrect** code for this rule:
9
10
 
10
11
  ```js
11
- cy.pause();
12
- cy.get('selector').pause();
12
+ cy.pause()
13
+ cy.get('selector').pause()
13
14
  ```
14
15
 
15
16
  Examples of **correct** code for this rule:
@@ -3,6 +3,7 @@
3
3
  💼 This rule is enabled in the ✅ `recommended` config.
4
4
 
5
5
  <!-- end auto-generated rule header -->
6
+
6
7
  ## Further Reading
7
8
 
8
9
  See [the Cypress Best Practices guide](https://on.cypress.io/best-practices#Unnecessary-Waiting).
@@ -15,11 +15,11 @@ cy.xpath('//div[@class=\"container\"]').click()
15
15
  Examples of **correct** code for this rule:
16
16
 
17
17
  ```js
18
- cy.get('[data-cy="container"]').click();
18
+ cy.get('[data-cy="container"]').click()
19
19
  ```
20
20
 
21
21
  ## Further Reading
22
22
 
23
23
  Both `@cypress/xpath` and `cypress-xpath` are deprecated.
24
24
 
25
- See [the Cypress Best Practices guide](https://docs.cypress.io/guides/references/best-practices.html#Selecting-Elements).
25
+ See [the Cypress Best Practices guide](https://docs.cypress.io/app/core-concepts/best-practices.html#Selecting-Elements).
@@ -1,6 +1,7 @@
1
1
  # Require `data-*` attribute selectors (`cypress/require-data-selectors`)
2
2
 
3
3
  <!-- end auto-generated rule header -->
4
+
4
5
  Require `cy.get` to use only selectors that target `data-*` attributes.
5
6
 
6
7
  > Note: If you use this rule, consider only using the `warn` error level, since using `data-*` attribute selectors may not always be possible.
@@ -10,11 +11,14 @@ Require `cy.get` to use only selectors that target `data-*` attributes.
10
11
  Examples of **incorrect** code for this rule:
11
12
 
12
13
  ```js
13
- cy.get(".a")
14
+ cy.get('.a')
14
15
  cy.get('[daedta-cy=submit]').click()
15
16
  cy.get('[d-cy=submit]')
16
- cy.get(".btn-large").click()
17
- cy.get(".btn-.large").click()
17
+ cy.get('.btn-large').click()
18
+ cy.get('.btn-.large').click()
19
+
20
+ const CLASS_SELECTOR = ".my-class";
21
+ cy.get(CLASS_SELECTOR)
18
22
  ```
19
23
 
20
24
  Examples of **correct** code for this rule:
@@ -22,8 +26,14 @@ Examples of **correct** code for this rule:
22
26
  ```js
23
27
  cy.get('[data-cy=submit]').click()
24
28
  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()
25
35
  ```
26
36
 
27
37
  ## Further Reading
28
38
 
29
- See [the Cypress Best Practices guide](https://docs.cypress.io/guides/references/best-practices.html#Selecting-Elements).
39
+ See [the Cypress Best Practices guide](https://docs.cypress.io/app/core-concepts/best-practices.html#Selecting-Elements).
@@ -3,6 +3,7 @@
3
3
  💼 This rule is enabled in the ✅ `recommended` config.
4
4
 
5
5
  <!-- end auto-generated rule header -->
6
+
6
7
  ### Options
7
8
 
8
9
  <!-- begin auto-generated rule options list -->
@@ -15,4 +16,4 @@
15
16
 
16
17
  ## Further Reading
17
18
 
18
- See [retry-ability guide](https://docs.cypress.io/guides/core-concepts/retry-ability#Actions-should-be-at-the-end-of-chains-not-the-middle).
19
+ See [retry-ability guide](https://docs.cypress.io/app/core-concepts/retry-ability#Actions-should-be-at-the-end-of-chains-not-the-middle).
package/lib/flat.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ import type { ESLint, Linter } from 'eslint'
2
+
3
+ declare const plugin: {
4
+ meta: { name: string, version: string }
5
+ configs: {
6
+ globals: Linter.Config<Linter.RulesRecord>
7
+ recommended: Linter.Config<Linter.RulesRecord>
8
+ }
9
+ rules: NonNullable<ESLint.Plugin['rules']>
10
+ }
11
+
12
+ export = plugin
@@ -1,5 +1,4 @@
1
1
  'use strict'
2
-
3
2
  module.exports = {
4
3
  meta: {
5
4
  type: 'suggestion',
@@ -16,9 +15,29 @@ module.exports = {
16
15
  },
17
16
 
18
17
  create(context) {
18
+ const variablesSet = new Set()
19
19
  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
+
20
39
  CallExpression(node) {
21
- if (isCallingCyGet(node) && !isDataArgument(node)) {
40
+ if (isCallingCyGet(node) && !isDataArgument(node, variablesSet)) {
22
41
  context.report({ node, messageId: 'unexpected' })
23
42
  }
24
43
  },
@@ -34,12 +53,24 @@ function isCallingCyGet(node) {
34
53
  && node.callee.property.name === 'get'
35
54
  }
36
55
 
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
43
74
  }
44
75
 
45
76
  function isAliasOrDataSelector(selector) {
@@ -7,7 +7,7 @@ const DESCRIPTION = 'disallow actions within chains'
7
7
 
8
8
  /**
9
9
  * Commands listed in the documentation with text: 'It is unsafe to chain further commands that rely on the subject after xxx.'
10
- * See {@link https://docs.cypress.io/guides/core-concepts/retry-ability#Actions-should-be-at-the-end-of-chains-not-the-middle Actions should be at the end of chains, not the middle}
10
+ * See {@link https://docs.cypress.io/app/core-concepts/retry-ability#Actions-should-be-at-the-end-of-chains-not-the-middle Actions should be at the end of chains, not the middle}
11
11
  * for more information.
12
12
  *
13
13
  * @type {string[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-cypress",
3
- "version": "5.1.0",
3
+ "version": "5.2.0",
4
4
  "description": "An ESLint plugin for projects using Cypress",
5
5
  "main": "./lib/flat.js",
6
6
  "exports": {
@@ -34,17 +34,20 @@
34
34
  "globals": "^16.2.0"
35
35
  },
36
36
  "devDependencies": {
37
- "@stylistic/eslint-plugin": "^4.4.0",
38
- "eslint": "^9.27.0",
39
- "eslint-plugin-eslint-plugin": "^6.4.0",
37
+ "@stylistic/eslint-plugin": "^5.3.1",
38
+ "eslint": "^9.35.0",
39
+ "eslint-plugin-eslint-plugin": "^7.0.0",
40
40
  "eslint-plugin-mocha": "^11.1.0",
41
41
  "husky": "^9.1.7",
42
- "semantic-release": "24.2.5",
43
- "vitest": "^3.1.4"
42
+ "prettier": "^3.6.2",
43
+ "semantic-release": "24.2.7",
44
+ "vitest": "^3.2.4"
44
45
  },
45
46
  "scripts": {
46
47
  "lint": "eslint",
47
48
  "lint-fix": "eslint --fix",
49
+ "format": "prettier --write .",
50
+ "format:check": "prettier --check .",
48
51
  "semantic-release": "semantic-release",
49
52
  "test": "vitest run",
50
53
  "prepare": "husky"