q9
This commit is contained in:
12
node_modules/eslint-plugin-cypress/.github/workflows/add-issue-triage-board.yml
generated
vendored
Normal file
12
node_modules/eslint-plugin-cypress/.github/workflows/add-issue-triage-board.yml
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
name: 'Add issue/PR to Triage Board'
|
||||
on:
|
||||
issues:
|
||||
types:
|
||||
- opened
|
||||
pull_request_target:
|
||||
types:
|
||||
- opened
|
||||
jobs:
|
||||
add-to-triage-project-board:
|
||||
uses: cypress-io/cypress/.github/workflows/triage_add_to_project.yml@develop
|
||||
secrets: inherit
|
||||
9
node_modules/eslint-plugin-cypress/.github/workflows/triage_closed_issue_comment.yml
generated
vendored
Normal file
9
node_modules/eslint-plugin-cypress/.github/workflows/triage_closed_issue_comment.yml
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
name: 'Handle Comment Workflow'
|
||||
on:
|
||||
issue_comment:
|
||||
types:
|
||||
- created
|
||||
jobs:
|
||||
closed-issue-comment:
|
||||
uses: cypress-io/cypress/.github/workflows/triage_handle_new_comments.yml@develop
|
||||
secrets: inherit
|
||||
1
node_modules/eslint-plugin-cypress/.husky/pre-commit
generated
vendored
Executable file
1
node_modules/eslint-plugin-cypress/.husky/pre-commit
generated
vendored
Executable file
@@ -0,0 +1 @@
|
||||
npm run lint
|
||||
1
node_modules/eslint-plugin-cypress/.node-version
generated
vendored
Normal file
1
node_modules/eslint-plugin-cypress/.node-version
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
20.12.2
|
||||
1
node_modules/eslint-plugin-cypress/.nvmrc
generated
vendored
Normal file
1
node_modules/eslint-plugin-cypress/.nvmrc
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
20.12.2
|
||||
50
node_modules/eslint-plugin-cypress/CONTRIBUTING.md
generated
vendored
Normal file
50
node_modules/eslint-plugin-cypress/CONTRIBUTING.md
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
# Contributing to cypress-io/eslint-plugin-cypress
|
||||
|
||||
Thanks for taking the time to contribute! :smile:
|
||||
|
||||
## Preparation
|
||||
|
||||
* Fork and clone this repository
|
||||
* Branch from the default `master` branch using a descriptive new branch name
|
||||
* Install dependencies with `npm ci`
|
||||
|
||||
## Rule references
|
||||
|
||||
* Refer to the [ESLint documentation](https://eslint.org/docs/latest/) and the [Custom Rules](https://eslint.org/docs/latest/extend/custom-rules) page
|
||||
|
||||
## New rule
|
||||
|
||||
To add a new rule:
|
||||
|
||||
* 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
|
||||
* Run the new rule generator `yo eslint:rule` and answer the questions
|
||||
- select "ESLint Plugin"
|
||||
- for "Type a short description of this rule" provide text which starts with one of "enforce", "require" or "disallow" (all lower case)
|
||||
* Yeoman creates three boilerplate files:
|
||||
- `docs/rules/<rule-id>.md`
|
||||
- `lib/rules/<rule-id>.js`
|
||||
- `test/rules/<rule-id>.js`
|
||||
* Run `npm run lint-fix`
|
||||
* Address the linting errors by editing `lib/rules/<rule-id>.js`
|
||||
- Add a `meta.messages` property (see [MessageIds](https://eslint.org/docs/latest/extend/custom-rules#messageids))
|
||||
- Select the appropriate `meta.type` property using `problem`, `suggestion`, or `layout`
|
||||
* Complete the new rule by adding content to the three files previously created
|
||||
* Run `eslint-doc-generator` to generate automated documentation sections (see [Document generation](#document-generation) below)
|
||||
* Review documentation changes
|
||||
* Run `npm run lint`
|
||||
* Run `npm test` to run [Jest](https://jestjs.io/) (or run `npm start` to run [Jest](https://jestjs.io/) in [watchAll](https://jestjs.io/docs/cli#--watchall) mode where it remains active and reruns when source changes are made)
|
||||
* Make sure all tests are passing
|
||||
* Add the rule to [legacy.js](https://github.com/cypress-io/eslint-plugin-cypress/blob/master/legacy.js) and to [flat.js](https://github.com/cypress-io/eslint-plugin-cypress/blob/master/lib/flat.js)
|
||||
* 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))
|
||||
* Create a PR from your branch
|
||||
|
||||
## Document generation
|
||||
|
||||
This plugin uses the ESLint [eslint-doc-generator](https://www.npmjs.com/package/eslint-doc-generator) to generate consistent documentation.
|
||||
* Install with `npm install eslint-doc-generator -g`
|
||||
* Run `eslint-doc-generator` in the root directory of the plugin
|
||||
|
||||
## Legacy tests
|
||||
|
||||
* The directory [tests-legacy](https://github.com/cypress-io/eslint-plugin-cypress/tree/master/tests-legacy) contains tests which are compatible with the legacy [ESLint v8 RuleTester](https://eslint.org/docs/v8.x/integrate/nodejs-api#ruletester) utility. It is not expected to add new rules to this set of tests.
|
||||
* The directory [tests](https://github.com/cypress-io/eslint-plugin-cypress/tree/master/tests) is for tests compatible with the current [ESLint RuleTester](https://eslint.org/docs/latest/integrate/nodejs-api#ruletester).
|
||||
147
node_modules/eslint-plugin-cypress/ESLINTRC-CONFIG.md
generated
vendored
Normal file
147
node_modules/eslint-plugin-cypress/ESLINTRC-CONFIG.md
generated
vendored
Normal file
@@ -0,0 +1,147 @@
|
||||
# Cypress ESLint Plugin - Legacy Config
|
||||
|
||||
This document supplements the [README](./README.md) document and describes how to use the Cypress ESLint Plugin (`eslint-plugin-cypress`) in a [deprecated ESLint legacy config environment](https://eslint.org/docs/latest/use/configure/configuration-files-deprecated). The use of flat configurations with this plugin is described in the [README](./README.md) document.
|
||||
|
||||
Usage with ESLint `9.x` is described.
|
||||
|
||||
## Deprecations
|
||||
|
||||
The use of `eslintrc` configurations with `eslint-plugin-cypress` is deprecated and support will be removed in a future version of this plugin. This is tied in to the ESLint announcement in the blog post [Flat config rollout plans](https://eslint.org/blog/2023/10/flat-config-rollout-plans/) from October 2023 which describes that the `eslintrc` configuration system is planned to be removed in the future ESLint `v10.0.0`. Users are encouraged to migrate to using a [flat configuration](https://eslint.org/docs/latest/use/configure/configuration-files).
|
||||
|
||||
## Installation
|
||||
|
||||
Use a minimum ESLint `9.x`.
|
||||
|
||||
```shell
|
||||
npm install eslint eslint-plugin-cypress --save-dev
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```shell
|
||||
yarn add eslint eslint-plugin-cypress --dev
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
To use a deprecated configuration with ESLint `v9`, such as `.eslintrc.json`, you must set the `ESLINT_USE_FLAT_CONFIG` environment variable to `false` (see [ESLint v9 > Configuration Files (Deprecated)](https://eslint.org/docs/latest/use/configure/configuration-files-deprecated)). The following examples use `json` format for the content of the configuration file:
|
||||
|
||||
```json
|
||||
{
|
||||
"plugins": [
|
||||
"cypress"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
You can add rules - see [Rules](./README.md#rules) for a list of the available rules:
|
||||
|
||||
```json
|
||||
{
|
||||
"rules": {
|
||||
"cypress/no-assigning-return-values": "error",
|
||||
"cypress/no-unnecessary-waiting": "error",
|
||||
"cypress/assertion-before-screenshot": "warn",
|
||||
"cypress/no-force": "warn",
|
||||
"cypress/no-async-tests": "error",
|
||||
"cypress/no-async-before": "error",
|
||||
"cypress/no-pause": "error",
|
||||
"cypress/no-debug": "error"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can allow certain globals provided by Cypress:
|
||||
|
||||
```json
|
||||
{
|
||||
"env": {
|
||||
"cypress/globals": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Recommended configuration
|
||||
|
||||
Use the recommended configuration and you can forego configuring _plugins_, _rules_, and _env_ individually. See [Rules](./README.md#rules) for which rules are included in the recommended configuration.
|
||||
|
||||
```json
|
||||
{
|
||||
"extends": [
|
||||
"plugin:cypress/recommended"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Rules
|
||||
|
||||
See the [Rules](./README.md#rules) list in the main [README](./README.md) document.
|
||||
|
||||
## Mocha and Chai
|
||||
|
||||
Cypress is built on top of [Mocha](https://on.cypress.io/guides/references/bundled-libraries#Mocha) and [Chai](https://on.cypress.io/guides/references/bundled-libraries#Chai). See the following sections for information on using ESLint plugins [eslint-plugin-mocha](https://www.npmjs.com/package/eslint-plugin-mocha) and [eslint-plugin-chai-friendly](https://www.npmjs.com/package/eslint-plugin-chai-friendly) together with `eslint-plugin-cypress`.
|
||||
|
||||
## Mocha `.only` and `.skip`
|
||||
|
||||
During test spec development, [Mocha exclusive tests](https://mochajs.org/#exclusive-tests) `.only` or [Mocha inclusive tests](https://mochajs.org/#inclusive-tests) `.skip` may be used to control which tests are executed, as described in the Cypress documentation [Excluding and Including Tests](https://on.cypress.io/guides/core-concepts/writing-and-organizing-tests#Excluding-and-Including-Tests). To apply corresponding rules, you can install and use [eslint-plugin-mocha](https://www.npmjs.com/package/eslint-plugin-mocha). The rule [mocha/no-exclusive-tests](https://github.com/lo1tuma/eslint-plugin-mocha/blob/main/docs/rules/no-exclusive-tests.md) detects the use of `.only` and the [mocha/no-skipped-tests](https://github.com/lo1tuma/eslint-plugin-mocha/blob/main/docs/rules/no-skipped-tests.md) rule detects the use of `.skip`:
|
||||
|
||||
```sh
|
||||
npm install --save-dev eslint-plugin-mocha
|
||||
```
|
||||
|
||||
In your `.eslintrc.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"plugins": [
|
||||
"cypress",
|
||||
"mocha"
|
||||
],
|
||||
"rules": {
|
||||
"mocha/no-exclusive-tests": "warn",
|
||||
"mocha/no-skipped-tests": "warn"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Or you can simply use the `cypress/recommended` and `mocha/recommended` configurations together, for example:
|
||||
|
||||
```json
|
||||
{
|
||||
"extends": [
|
||||
"plugin:cypress/recommended",
|
||||
"plugin:mocha/recommended"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Chai and `no-unused-expressions`
|
||||
|
||||
Using an assertion such as `expect(value).to.be.true` can fail the ESLint rule `no-unused-expressions` even though it's not an error in this case. To fix this, you can install and use [eslint-plugin-chai-friendly](https://www.npmjs.com/package/eslint-plugin-chai-friendly).
|
||||
|
||||
```sh
|
||||
npm install --save-dev eslint-plugin-chai-friendly
|
||||
```
|
||||
|
||||
In your `.eslintrc.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"plugins": [
|
||||
"cypress",
|
||||
"chai-friendly"
|
||||
],
|
||||
"rules": {
|
||||
"no-unused-expressions": 0,
|
||||
"chai-friendly/no-unused-expressions": 2
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Or you can simply add its `recommended` config:
|
||||
|
||||
```json
|
||||
{
|
||||
"extends": ["plugin:chai-friendly/recommended"]
|
||||
}
|
||||
```
|
||||
5
node_modules/eslint-plugin-cypress/FLAT-CONFIG.md
generated
vendored
Normal file
5
node_modules/eslint-plugin-cypress/FLAT-CONFIG.md
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
# Cypress ESLint Plugin - Flat Config
|
||||
|
||||
Please refer to the [README](./README.md) document where the previous contents of this document, describing how to use `eslint-plugin-cypress` with an ESLint `v9` (default) [flat configuration](https://eslint.org/docs/latest/use/configure/configuration-files), can now be found.
|
||||
|
||||
For instructions on using a deprecated [eslintrc-type](https://eslint.org/docs/latest/use/configure/configuration-files-deprecated) config file from previous ESLint `v8` versions and below, please refer to the [ESLINTRC-CONFIG](./ESLINTRC-CONFIG.md) document.
|
||||
21
node_modules/eslint-plugin-cypress/LICENSE
generated
vendored
Normal file
21
node_modules/eslint-plugin-cypress/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Cypress.io
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
221
node_modules/eslint-plugin-cypress/README.md
generated
vendored
Normal file
221
node_modules/eslint-plugin-cypress/README.md
generated
vendored
Normal file
@@ -0,0 +1,221 @@
|
||||
# Cypress ESLint Plugin [](https://circleci.com/gh/cypress-io/eslint-plugin-cypress/tree/master)
|
||||
|
||||
An [ESLint](https://eslint.org) plugin for your [Cypress](https://cypress.io) tests.
|
||||
|
||||
Note: If you installed ESLint globally then you must also install `eslint-plugin-cypress` globally.
|
||||
|
||||
## Installation
|
||||
|
||||
Prerequisites: [ESLint](https://www.npmjs.com/package/eslint) `v9`. Lower versions are no longer supported.
|
||||
|
||||
```sh
|
||||
npm install eslint eslint-plugin-cypress --save-dev
|
||||
```
|
||||
or
|
||||
```sh
|
||||
yarn add eslint eslint-plugin-cypress --dev
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
ESLint `v9` uses a [Flat config file](https://eslint.org/docs/latest/use/configure/configuration-files) format with filename `eslint.config.*js` by default. For instructions on using a deprecated [eslintrc-type](https://eslint.org/docs/latest/use/configure/configuration-files-deprecated) config file from previous ESLint versions, please refer to the [ESLINTRC-CONFIG](./ESLINTRC-CONFIG.md) document.
|
||||
|
||||
To set up a flat configuration, add a file `eslint.config.mjs` to the root directory of your Cypress project and include the following instructions to import the available flat configurations using:
|
||||
|
||||
```shell
|
||||
import pluginCypress from 'eslint-plugin-cypress/flat'
|
||||
```
|
||||
|
||||
## Configurations
|
||||
|
||||
There are two specific flat configurations available:
|
||||
|
||||
| Configuration | Content |
|
||||
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `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). This version no longer specifies `languageOptions` for `ecmaVersion` and `sourceType` - see ESLint [JavaScript languageOptions](https://eslint.org/docs/latest/use/configure/language-options#specifying-javascript-options). There are no default rules enabled in this configuration. |
|
||||
| `configs.recommended` | enables [recommended Rules](#rules). It includes also `configs.global` (see above). |
|
||||
|
||||
## Rules
|
||||
|
||||
These rules enforce some of the [best practices recommended for using Cypress](https://on.cypress.io/best-practices).
|
||||
|
||||
<!-- begin auto-generated rules list -->
|
||||
|
||||
💼 Configurations enabled in.\
|
||||
✅ Set in the `recommended` configuration.
|
||||
|
||||
| Name | Description | 💼 |
|
||||
| :----------------------------------------------------------------------- | :--------------------------------------------------------- | :- |
|
||||
| [assertion-before-screenshot](docs/rules/assertion-before-screenshot.md) | require screenshots to be preceded by an assertion | |
|
||||
| [no-assigning-return-values](docs/rules/no-assigning-return-values.md) | disallow assigning return values of `cy` calls | ✅ |
|
||||
| [no-async-before](docs/rules/no-async-before.md) | disallow using `async`/`await` in Cypress `before` methods | |
|
||||
| [no-async-tests](docs/rules/no-async-tests.md) | disallow using `async`/`await` in Cypress test cases | ✅ |
|
||||
| [no-debug](docs/rules/no-debug.md) | disallow using `cy.debug()` calls | |
|
||||
| [no-force](docs/rules/no-force.md) | disallow using `force: true` with action commands | |
|
||||
| [no-pause](docs/rules/no-pause.md) | disallow using `cy.pause()` calls | |
|
||||
| [no-unnecessary-waiting](docs/rules/no-unnecessary-waiting.md) | disallow waiting for arbitrary time periods | ✅ |
|
||||
| [require-data-selectors](docs/rules/require-data-selectors.md) | require `data-*` attribute selectors | |
|
||||
| [unsafe-to-chain-command](docs/rules/unsafe-to-chain-command.md) | disallow actions within chains | ✅ |
|
||||
|
||||
<!-- end auto-generated rules list -->
|
||||
|
||||
## Usage examples
|
||||
|
||||
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.
|
||||
|
||||
### Cypress
|
||||
|
||||
All rules from `eslint-plugin-cypress` are available through `eslint-plugin-cypress/flat` and can be individually activated.
|
||||
- [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`
|
||||
|
||||
```js
|
||||
import pluginCypress from 'eslint-plugin-cypress/flat'
|
||||
export default [
|
||||
{
|
||||
plugins: {
|
||||
cypress: pluginCypress
|
||||
},
|
||||
rules: {
|
||||
'cypress/unsafe-to-chain-command': 'error'
|
||||
}
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### Cypress recommended
|
||||
|
||||
The `eslint-plugin-cypress` [recommended rules](#rules) `configs.recommended` are activated, except for
|
||||
- [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`
|
||||
|
||||
```js
|
||||
import pluginCypress from 'eslint-plugin-cypress/flat'
|
||||
export default [
|
||||
pluginCypress.configs.recommended,
|
||||
{
|
||||
rules: {
|
||||
'cypress/no-unnecessary-waiting': 'off'
|
||||
}
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### Cypress globals
|
||||
|
||||
The `configs.globals` are activated.
|
||||
|
||||
```js
|
||||
import pluginCypress from 'eslint-plugin-cypress/flat'
|
||||
export default [
|
||||
pluginCypress.configs.globals
|
||||
]
|
||||
```
|
||||
|
||||
## Disable rules
|
||||
|
||||
You can disable specific rules per file, for a portion of a file, or for a single line. See the [ESLint rules](https://eslint.org/docs/latest/use/configure/rules#disabling-rules) documentation. For example ...
|
||||
|
||||
Disable the `cypress/no-unnecessary-waiting` rule for the entire file by placing this at the start of the file:
|
||||
|
||||
```js
|
||||
/* eslint-disable cypress/no-unnecessary-waiting */
|
||||
```
|
||||
|
||||
Disable the `cypress/no-unnecessary-waiting` rule for only a portion of the file:
|
||||
|
||||
```js
|
||||
it('waits for a second', () => {
|
||||
...
|
||||
/* eslint-disable cypress/no-unnecessary-waiting */
|
||||
cy.wait(1000)
|
||||
/* eslint-enable cypress/no-unnecessary-waiting */
|
||||
...
|
||||
})
|
||||
```
|
||||
|
||||
Disable the `cypress/no-unnecessary-waiting` rule for a specific line:
|
||||
|
||||
```js
|
||||
it('waits for a second', () => {
|
||||
...
|
||||
cy.wait(1000) // eslint-disable-line cypress/no-unnecessary-waiting
|
||||
...
|
||||
})
|
||||
```
|
||||
|
||||
You can also disable a rule for the next line:
|
||||
|
||||
```js
|
||||
it('waits for a second', () => {
|
||||
...
|
||||
// eslint-disable-next-line cypress/no-unnecessary-waiting
|
||||
cy.wait(1000)
|
||||
...
|
||||
})
|
||||
```
|
||||
|
||||
## Mocha and Chai
|
||||
|
||||
Cypress is built on top of [Mocha](https://on.cypress.io/guides/references/bundled-libraries#Mocha) and [Chai](https://on.cypress.io/guides/references/bundled-libraries#Chai). See the following sections for information on using ESLint plugins [eslint-plugin-mocha](https://www.npmjs.com/package/eslint-plugin-mocha) and [eslint-plugin-chai-friendly](https://www.npmjs.com/package/eslint-plugin-chai-friendly) together with `eslint-plugin-cypress`.
|
||||
|
||||
## Mocha `.only` and `.skip`
|
||||
|
||||
During test spec development, [Mocha exclusive tests](https://mochajs.org/#exclusive-tests) `.only` or [Mocha inclusive tests](https://mochajs.org/#inclusive-tests) `.skip` may be used to control which tests are executed, as described in the Cypress documentation [Excluding and Including Tests](https://on.cypress.io/guides/core-concepts/writing-and-organizing-tests#Excluding-and-Including-Tests). To apply corresponding rules, you can install and use [eslint-plugin-mocha](https://www.npmjs.com/package/eslint-plugin-mocha). The rule [mocha/no-exclusive-tests](https://github.com/lo1tuma/eslint-plugin-mocha/blob/main/docs/rules/no-exclusive-tests.md) detects the use of `.only` and the [mocha/no-skipped-tests](https://github.com/lo1tuma/eslint-plugin-mocha/blob/main/docs/rules/no-skipped-tests.md) rule detects the use of `.skip`.
|
||||
|
||||
### Cypress and Mocha recommended
|
||||
|
||||
[eslint-plugin-mocha](https://www.npmjs.com/package/eslint-plugin-mocha) is added to the example [Cypress recommended](#cypress-recommended). This plugin offers a flat file recommended option `configs.flat.recommended`.
|
||||
|
||||
The settings for individual `mocha` rules from the `configs.flat.recommended` option are changed.
|
||||
- [mocha/no-exclusive-tests](https://github.com/lo1tuma/eslint-plugin-mocha/blob/main/docs/rules/no-exclusive-tests.md) and [mocha/no-skipped-tests](https://github.com/lo1tuma/eslint-plugin-mocha/blob/main/docs/rules/no-skipped-tests.md) are set to `error` instead of `warn`
|
||||
- [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`
|
||||
|
||||
```shell
|
||||
npm install eslint-plugin-mocha@^10.5.0 --save-dev
|
||||
```
|
||||
|
||||
```js
|
||||
import pluginMocha from 'eslint-plugin-mocha'
|
||||
import pluginCypress from 'eslint-plugin-cypress/flat'
|
||||
export default [
|
||||
pluginMocha.configs.flat.recommended,
|
||||
pluginCypress.configs.recommended,
|
||||
{
|
||||
rules: {
|
||||
'mocha/no-exclusive-tests': 'error',
|
||||
'mocha/no-skipped-tests': 'error',
|
||||
'mocha/no-mocha-arrows': 'off',
|
||||
'cypress/no-unnecessary-waiting': 'off'
|
||||
}
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### Cypress and Chai recommended
|
||||
|
||||
Using an assertion such as `expect(value).to.be.true` can fail the ESLint rule `no-unused-expressions` even though it's not an error in this case. To fix this, you can install and use [eslint-plugin-chai-friendly](https://www.npmjs.com/package/eslint-plugin-chai-friendly).
|
||||
|
||||
[eslint-plugin-chai-friendly](https://www.npmjs.com/package/eslint-plugin-chai-friendly) is combined with the Cypress plugin `eslint-plugin-cypress`.
|
||||
|
||||
The recommended rules for both plugins are used: `pluginCypress.configs.recommended` and `pluginChaiFriendly.configs.recommendedFlat`:
|
||||
|
||||
```shell
|
||||
npm install eslint-plugin-chai-friendly@^1.0.1 --save-dev
|
||||
```
|
||||
|
||||
```js
|
||||
import pluginCypress from 'eslint-plugin-cypress/flat'
|
||||
import pluginChaiFriendly from 'eslint-plugin-chai-friendly'
|
||||
export default [
|
||||
pluginCypress.configs.recommended,
|
||||
pluginChaiFriendly.configs.recommendedFlat,
|
||||
{
|
||||
rules: {
|
||||
'cypress/no-unnecessary-waiting': 'off',
|
||||
},
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
Please see our [Contributing Guideline](./CONTRIBUTING.md) which explains how to contribute rules or other fixes and features to the repo.
|
||||
82
node_modules/eslint-plugin-cypress/circle.yml
generated
vendored
Normal file
82
node_modules/eslint-plugin-cypress/circle.yml
generated
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
version: 2.1
|
||||
|
||||
workflows:
|
||||
version: 2.1
|
||||
main:
|
||||
jobs:
|
||||
- lint
|
||||
- test-v8
|
||||
- test-v9
|
||||
- release:
|
||||
requires:
|
||||
- lint
|
||||
- test-v8
|
||||
- test-v9
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
docker:
|
||||
- image: cimg/node:22.11.0
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Install dependencies
|
||||
command: npm ci
|
||||
- run:
|
||||
name: Show ESLint version
|
||||
command: npx eslint --version
|
||||
- run:
|
||||
name: Lint code
|
||||
command: npm run lint
|
||||
|
||||
test-v8:
|
||||
docker:
|
||||
- image: cimg/node:22.11.0
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Install dependencies
|
||||
command: npm ci
|
||||
- run:
|
||||
name: Install ESLint 8
|
||||
command: npm install eslint@8
|
||||
- run:
|
||||
name: Show ESLint version
|
||||
command: npx eslint --version
|
||||
- run:
|
||||
name: Test ESLint 8
|
||||
command: npm run test:legacy
|
||||
|
||||
test-v9:
|
||||
docker:
|
||||
- image: cimg/node:22.11.0
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Install dependencies
|
||||
command: npm ci
|
||||
- run:
|
||||
name: Install ESLint 9
|
||||
command: npm install eslint@9
|
||||
- run:
|
||||
name: Show ESLint version
|
||||
command: npx eslint --version
|
||||
- run:
|
||||
name: Test ESLint 9
|
||||
command: npm test
|
||||
|
||||
release:
|
||||
docker:
|
||||
- image: cimg/node:22.11.0
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Install dependencies
|
||||
command: npm ci
|
||||
- run:
|
||||
name: Run semantic release
|
||||
command: npm run semantic-release
|
||||
25
node_modules/eslint-plugin-cypress/docs/rules/assertion-before-screenshot.md
generated
vendored
Normal file
25
node_modules/eslint-plugin-cypress/docs/rules/assertion-before-screenshot.md
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
# Require screenshots to be preceded by an assertion (`cypress/assertion-before-screenshot`)
|
||||
|
||||
<!-- end auto-generated rule header -->
|
||||
If you take screenshots without assertions then you may get different screenshots depending on timing.
|
||||
|
||||
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.
|
||||
|
||||
## Rule Details
|
||||
|
||||
This rule checks there is an assertion making sure your application state is correct before doing a screenshot. This makes sure the result of the screenshot will be consistent.
|
||||
|
||||
Examples of **incorrect** code for this rule:
|
||||
|
||||
```js
|
||||
cy.visit('myUrl');
|
||||
cy.screenshot();
|
||||
```
|
||||
|
||||
Examples of **correct** code for this rule:
|
||||
|
||||
```js
|
||||
cy.visit('myUrl');
|
||||
cy.get('[data-test-id="my-element"]').should('be.visible');
|
||||
cy.screenshot();
|
||||
```
|
||||
8
node_modules/eslint-plugin-cypress/docs/rules/no-assigning-return-values.md
generated
vendored
Normal file
8
node_modules/eslint-plugin-cypress/docs/rules/no-assigning-return-values.md
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
# Disallow assigning return values of `cy` calls (`cypress/no-assigning-return-values`)
|
||||
|
||||
💼 This rule is enabled in the ✅ `recommended` config.
|
||||
|
||||
<!-- end auto-generated rule header -->
|
||||
## Further Reading
|
||||
|
||||
See [the Cypress Best Practices guide](https://on.cypress.io/best-practices#Assigning-Return-Values).
|
||||
51
node_modules/eslint-plugin-cypress/docs/rules/no-async-before.md
generated
vendored
Normal file
51
node_modules/eslint-plugin-cypress/docs/rules/no-async-before.md
generated
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
# Disallow using `async`/`await` in Cypress `before` methods (`cypress/no-async-before`)
|
||||
|
||||
<!-- end auto-generated rule header -->
|
||||
Cypress commands that return a promise may cause side effects in `before`/`beforeEach` hooks, possibly causing unexpected behavior.
|
||||
|
||||
## Rule Details
|
||||
|
||||
This rule disallows using `async` `before` and `beforeEach` functions.
|
||||
|
||||
Examples of **incorrect** code for this rule:
|
||||
|
||||
```js
|
||||
describe('my feature', () => {
|
||||
before('my test case', async () => {
|
||||
await cy.get('.myClass')
|
||||
// other operations
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
```js
|
||||
describe('my feature', () => {
|
||||
before('my test case', async () => {
|
||||
cy
|
||||
.get('.myClass')
|
||||
.click()
|
||||
|
||||
await someAsyncFunction()
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
Examples of **correct** code for this rule:
|
||||
|
||||
```js
|
||||
describe('my feature', () => {
|
||||
before('my test case', () => {
|
||||
cy.get('.myClass')
|
||||
// other operations
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
## When Not To Use It
|
||||
|
||||
If there are genuine use-cases for using `async/await` in your `before` hooks then you may not want to include this rule (or at least demote it to a warning).
|
||||
|
||||
## Further Reading
|
||||
|
||||
- [Mixing Async and Sync code](https://on.cypress.io/guides/core-concepts/introduction-to-cypress#Mixing-Async-and-Sync-code)
|
||||
- [Commands Are Asynchronous](https://on.cypress.io/guides/core-concepts/introduction-to-cypress.html#Commands-Are-Asynchronous)
|
||||
54
node_modules/eslint-plugin-cypress/docs/rules/no-async-tests.md
generated
vendored
Normal file
54
node_modules/eslint-plugin-cypress/docs/rules/no-async-tests.md
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
# Disallow using `async`/`await` in Cypress test cases (`cypress/no-async-tests`)
|
||||
|
||||
💼 This rule is enabled in the ✅ `recommended` config.
|
||||
|
||||
<!-- end auto-generated rule header -->
|
||||
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.
|
||||
An `async` function returns a promise under the hood, so a test using an `async` function will also error.
|
||||
|
||||
## Rule Details
|
||||
|
||||
This rule disallows using `async` test functions.
|
||||
|
||||
Examples of **incorrect** code for this rule:
|
||||
|
||||
```js
|
||||
describe('my feature', () => {
|
||||
it('my test case', async () => {
|
||||
await cy.get('.myClass')
|
||||
// other operations
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
```js
|
||||
describe('my feature', () => {
|
||||
it('my test case', async () => {
|
||||
cy
|
||||
.get('.myClass')
|
||||
.click()
|
||||
|
||||
await someAsyncFunction()
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
Examples of **correct** code for this rule:
|
||||
|
||||
```js
|
||||
describe('my feature', () => {
|
||||
it('my test case', () => {
|
||||
cy.get('.myClass')
|
||||
// other operations
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
## When Not To Use It
|
||||
|
||||
If there are genuine use-cases for using `async/await` in your test cases then you may not want to include this rule (or at least demote it to a warning).
|
||||
|
||||
## Further Reading
|
||||
|
||||
- [Mixing Async and Sync code](https://on.cypress.io/guides/core-concepts/introduction-to-cypress#Mixing-Async-and-Sync-code)
|
||||
- [Commands Are Asynchronous](https://on.cypress.io/guides/core-concepts/introduction-to-cypress.html#Commands-Are-Asynchronous)
|
||||
19
node_modules/eslint-plugin-cypress/docs/rules/no-debug.md
generated
vendored
Normal file
19
node_modules/eslint-plugin-cypress/docs/rules/no-debug.md
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
# Disallow using `cy.debug()` calls (`cypress/no-debug`)
|
||||
|
||||
<!-- end auto-generated rule header -->
|
||||
It is recommended to remove any [cy.debug](https://on.cypress.io/debug) commands before committing specs to avoid other developers getting unexpected results.
|
||||
|
||||
## Rule Details
|
||||
|
||||
Examples of **incorrect** code for this rule:
|
||||
|
||||
```js
|
||||
cy.debug();
|
||||
cy.get('selector').debug();
|
||||
```
|
||||
|
||||
Examples of **correct** code for this rule:
|
||||
|
||||
```js
|
||||
cy.get('selector')
|
||||
```
|
||||
48
node_modules/eslint-plugin-cypress/docs/rules/no-force.md
generated
vendored
Normal file
48
node_modules/eslint-plugin-cypress/docs/rules/no-force.md
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
# Disallow using `force: true` with action commands (`cypress/no-force`)
|
||||
|
||||
<!-- end auto-generated rule header -->
|
||||
Using `force: true` on inputs appears to be confusing rather than helpful.
|
||||
It usually silences the actual problem instead of providing a way to overcome it.
|
||||
See [Cypress Core Concepts](https://docs.cypress.io/guides/core-concepts/interacting-with-elements.html#Forcing).
|
||||
|
||||
If enabling this rule, it's recommended to set the severity to `warn`.
|
||||
|
||||
## Rule Details
|
||||
|
||||
This rule disallows using the `force` option on:[`.click()`](https://on.cypress.io/click),
|
||||
[`.dblclick()`](https://on.cypress.io/dblclick), [`.type()`](https://on.cypress.io/type),
|
||||
[`.rightclick()`](https://on.cypress.io/rightclick), [`.select()`](https://on.cypress.io/select),
|
||||
[`.focus()`](https://on.cypress.io/focus), [`.check()`](https://on.cypress.io/check),
|
||||
and [`.trigger()`](https://on.cypress.io/trigger).
|
||||
|
||||
Examples of **incorrect** code for this rule:
|
||||
|
||||
```js
|
||||
cy.get('button').click({force: true})
|
||||
cy.get('button').dblclick({force: true})
|
||||
cy.get('input').type('somth', {force: true})
|
||||
cy.get('div').find('.foo').find('.bar').trigger('change', {force: true})
|
||||
cy.get('input').trigger('click', {force: true})
|
||||
cy.get('input').rightclick({force: true})
|
||||
cy.get('input').check({force: true})
|
||||
cy.get('input').select({force: true})
|
||||
cy.get('input').focus({force: true})
|
||||
```
|
||||
|
||||
Examples of **correct** code for this rule:
|
||||
|
||||
```js
|
||||
cy.get('button').click()
|
||||
cy.get('button').click({multiple: true})
|
||||
cy.get('button').dblclick()
|
||||
cy.get('input').type('somth')
|
||||
cy.get('input').trigger('click', {anyoption: true})
|
||||
cy.get('input').rightclick({anyoption: true})
|
||||
cy.get('input').check()
|
||||
cy.get('input').select()
|
||||
cy.get('input').focus()
|
||||
```
|
||||
|
||||
## When Not To Use It
|
||||
|
||||
If you don't mind using `{ force: true }` with action commands, then turn this rule off.
|
||||
19
node_modules/eslint-plugin-cypress/docs/rules/no-pause.md
generated
vendored
Normal file
19
node_modules/eslint-plugin-cypress/docs/rules/no-pause.md
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
# Disallow using `cy.pause()` calls (`cypress/no-pause`)
|
||||
|
||||
<!-- end auto-generated rule header -->
|
||||
It is recommended to remove any [cy.pause](https://on.cypress.io/pause) commands before committing specs to avoid other developers getting unexpected results.
|
||||
|
||||
## Rule Details
|
||||
|
||||
Examples of **incorrect** code for this rule:
|
||||
|
||||
```js
|
||||
cy.pause();
|
||||
cy.get('selector').pause();
|
||||
```
|
||||
|
||||
Examples of **correct** code for this rule:
|
||||
|
||||
```js
|
||||
cy.get('selector')
|
||||
```
|
||||
8
node_modules/eslint-plugin-cypress/docs/rules/no-unnecessary-waiting.md
generated
vendored
Normal file
8
node_modules/eslint-plugin-cypress/docs/rules/no-unnecessary-waiting.md
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
# Disallow waiting for arbitrary time periods (`cypress/no-unnecessary-waiting`)
|
||||
|
||||
💼 This rule is enabled in the ✅ `recommended` config.
|
||||
|
||||
<!-- end auto-generated rule header -->
|
||||
## Further Reading
|
||||
|
||||
See [the Cypress Best Practices guide](https://on.cypress.io/best-practices#Unnecessary-Waiting).
|
||||
29
node_modules/eslint-plugin-cypress/docs/rules/require-data-selectors.md
generated
vendored
Normal file
29
node_modules/eslint-plugin-cypress/docs/rules/require-data-selectors.md
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
# Require `data-*` attribute selectors (`cypress/require-data-selectors`)
|
||||
|
||||
<!-- end auto-generated rule header -->
|
||||
Require `cy.get` to use only selectors that target `data-*` attributes.
|
||||
|
||||
> Note: If you use this rule, consider only using the `warn` error level, since using `data-*` attribute selectors may not always be possible.
|
||||
|
||||
## Rule Details
|
||||
|
||||
Examples of **incorrect** code for this rule:
|
||||
|
||||
```js
|
||||
cy.get(".a")
|
||||
cy.get('[daedta-cy=submit]').click()
|
||||
cy.get('[d-cy=submit]')
|
||||
cy.get(".btn-large").click()
|
||||
cy.get(".btn-.large").click()
|
||||
```
|
||||
|
||||
Examples of **correct** code for this rule:
|
||||
|
||||
```js
|
||||
cy.get('[data-cy=submit]').click()
|
||||
cy.get('[data-QA=submit]')
|
||||
```
|
||||
|
||||
## Further Reading
|
||||
|
||||
See [the Cypress Best Practices guide](https://docs.cypress.io/guides/references/best-practices.html#Selecting-Elements).
|
||||
18
node_modules/eslint-plugin-cypress/docs/rules/unsafe-to-chain-command.md
generated
vendored
Normal file
18
node_modules/eslint-plugin-cypress/docs/rules/unsafe-to-chain-command.md
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
# Disallow actions within chains (`cypress/unsafe-to-chain-command`)
|
||||
|
||||
💼 This rule is enabled in the ✅ `recommended` config.
|
||||
|
||||
<!-- end auto-generated rule header -->
|
||||
### Options
|
||||
|
||||
<!-- begin auto-generated rule options list -->
|
||||
|
||||
| Name | Description | Type | Default |
|
||||
| :-------- | :---------------------------------------------------------- | :---- | :------ |
|
||||
| `methods` | An additional list of methods to check for unsafe chaining. | Array | `[]` |
|
||||
|
||||
<!-- end auto-generated rule options list -->
|
||||
|
||||
## Further Reading
|
||||
|
||||
See [retry-ability guide](https://docs.cypress.io/guides/core-concepts/retry-ability#Actions-should-be-at-the-end-of-chains-not-the-middle).
|
||||
29
node_modules/eslint-plugin-cypress/eslint.config.mjs
generated
vendored
Normal file
29
node_modules/eslint-plugin-cypress/eslint.config.mjs
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
import globals from 'globals'
|
||||
import pluginJs from '@eslint/js'
|
||||
import eslintPlugin from 'eslint-plugin-eslint-plugin'
|
||||
import nodePlugin from 'eslint-plugin-n'
|
||||
import mochaPlugin from 'eslint-plugin-mocha'
|
||||
|
||||
export default [
|
||||
pluginJs.configs.recommended,
|
||||
eslintPlugin.configs['flat/recommended'],
|
||||
nodePlugin.configs['flat/recommended-script'],
|
||||
mochaPlugin.configs.flat.recommended,
|
||||
{
|
||||
languageOptions: {
|
||||
globals: globals.node
|
||||
},
|
||||
rules: {
|
||||
'no-redeclare': 'off',
|
||||
'eslint-plugin/require-meta-docs-url':
|
||||
['error', { 'pattern': 'https://github.com/cypress-io/eslint-plugin-cypress/blob/master/docs/rules/{{name}}.md' }],
|
||||
'eslint-plugin/require-meta-docs-description': 'error',
|
||||
'eslint-plugin/meta-property-ordering': 'error',
|
||||
'eslint-plugin/test-case-property-ordering': 'error',
|
||||
'n/no-extraneous-require':
|
||||
['error', { 'allowModules': ['jest-config'] }],
|
||||
'mocha/no-mocha-arrows': 'off',
|
||||
'mocha/no-setup-in-describe': 'off'
|
||||
}
|
||||
},
|
||||
]
|
||||
6
node_modules/eslint-plugin-cypress/jest.config-legacy.js
generated
vendored
Normal file
6
node_modules/eslint-plugin-cypress/jest.config-legacy.js
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
const { defaults } = require('jest-config')
|
||||
|
||||
module.exports = {
|
||||
testMatch: ['**/tests-legacy/**/*.[jt]s?(x)'],
|
||||
testPathIgnorePatterns: [...defaults.testPathIgnorePatterns, '.history'],
|
||||
}
|
||||
6
node_modules/eslint-plugin-cypress/jest.config.js
generated
vendored
Normal file
6
node_modules/eslint-plugin-cypress/jest.config.js
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
const { defaults } = require('jest-config')
|
||||
|
||||
module.exports = {
|
||||
testMatch: ['**/tests/**/*.[jt]s?(x)'],
|
||||
testPathIgnorePatterns: [...defaults.testPathIgnorePatterns, '.history'],
|
||||
}
|
||||
34
node_modules/eslint-plugin-cypress/legacy.js
generated
vendored
Normal file
34
node_modules/eslint-plugin-cypress/legacy.js
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
const globals = require('globals')
|
||||
|
||||
module.exports = {
|
||||
rules: {
|
||||
'no-assigning-return-values': require('./lib/rules/no-assigning-return-values'),
|
||||
'unsafe-to-chain-command': require('./lib/rules/unsafe-to-chain-command'),
|
||||
'no-unnecessary-waiting': require('./lib/rules/no-unnecessary-waiting'),
|
||||
'no-async-before': require('./lib/rules/no-async-before'),
|
||||
'no-async-tests': require('./lib/rules/no-async-tests'),
|
||||
'assertion-before-screenshot': require('./lib/rules/assertion-before-screenshot'),
|
||||
'require-data-selectors': require('./lib/rules/require-data-selectors'),
|
||||
'no-force': require('./lib/rules/no-force'),
|
||||
'no-pause': require('./lib/rules/no-pause'),
|
||||
'no-debug': require('./lib/rules/no-debug'),
|
||||
},
|
||||
configs: {
|
||||
recommended: require('./lib/config/recommended'),
|
||||
},
|
||||
environments: {
|
||||
globals: {
|
||||
globals: Object.assign({
|
||||
cy: false,
|
||||
Cypress: false,
|
||||
expect: false,
|
||||
assert: false,
|
||||
chai: false,
|
||||
}, globals.browser, globals.mocha),
|
||||
parserOptions: {
|
||||
ecmaVersion: 2019,
|
||||
sourceType: 'module',
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
14
node_modules/eslint-plugin-cypress/lib/config/recommended.js
generated
vendored
Normal file
14
node_modules/eslint-plugin-cypress/lib/config/recommended.js
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
'use strict'
|
||||
|
||||
module.exports = {
|
||||
plugins: ['cypress'],
|
||||
env: {
|
||||
'cypress/globals': true,
|
||||
},
|
||||
rules: {
|
||||
'cypress/no-assigning-return-values': 'error',
|
||||
'cypress/no-unnecessary-waiting': 'error',
|
||||
'cypress/no-async-tests': 'error',
|
||||
'cypress/unsafe-to-chain-command': 'error',
|
||||
},
|
||||
}
|
||||
62
node_modules/eslint-plugin-cypress/lib/flat.js
generated
vendored
Normal file
62
node_modules/eslint-plugin-cypress/lib/flat.js
generated
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
const globals = require('globals')
|
||||
const { name, version } = require('../package.json')
|
||||
|
||||
const plugin = {
|
||||
meta: { name, version },
|
||||
configs: {},
|
||||
rules: {
|
||||
'no-assigning-return-values': require('./rules/no-assigning-return-values'),
|
||||
'unsafe-to-chain-command': require('./rules/unsafe-to-chain-command'),
|
||||
'no-unnecessary-waiting': require('./rules/no-unnecessary-waiting'),
|
||||
'no-async-before': require('./rules/no-async-before'),
|
||||
'no-async-tests': require('./rules/no-async-tests'),
|
||||
'assertion-before-screenshot': require('./rules/assertion-before-screenshot'),
|
||||
'require-data-selectors': require('./rules/require-data-selectors'),
|
||||
'no-force': require('./rules/no-force'),
|
||||
'no-pause': require('./rules/no-pause'),
|
||||
'no-debug': require('./rules/no-debug'),
|
||||
},
|
||||
}
|
||||
|
||||
const commonGlobals =
|
||||
Object.assign({
|
||||
cy: false,
|
||||
Cypress: false,
|
||||
expect: false,
|
||||
assert: false,
|
||||
chai: false,
|
||||
}, globals.browser, globals.mocha)
|
||||
|
||||
Object.assign(plugin.configs, {
|
||||
globals: {
|
||||
name: 'cypress/globals',
|
||||
plugins: {
|
||||
cypress: plugin
|
||||
},
|
||||
languageOptions: {
|
||||
globals:
|
||||
commonGlobals,
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Object.assign(plugin.configs, {
|
||||
recommended: {
|
||||
name: 'cypress/recommended',
|
||||
plugins: {
|
||||
cypress: plugin
|
||||
},
|
||||
rules: {
|
||||
'cypress/no-assigning-return-values': 'error',
|
||||
'cypress/no-unnecessary-waiting': 'error',
|
||||
'cypress/no-async-tests': 'error',
|
||||
'cypress/unsafe-to-chain-command': 'error',
|
||||
},
|
||||
languageOptions: {
|
||||
globals:
|
||||
commonGlobals,
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
module.exports = plugin
|
||||
112
node_modules/eslint-plugin-cypress/lib/rules/assertion-before-screenshot.js
generated
vendored
Normal file
112
node_modules/eslint-plugin-cypress/lib/rules/assertion-before-screenshot.js
generated
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
'use strict'
|
||||
|
||||
const assertionCommands = [
|
||||
// assertions
|
||||
'should',
|
||||
'and',
|
||||
'contains',
|
||||
|
||||
// retries until it gets something
|
||||
'get',
|
||||
|
||||
// not an assertion, but unlikely to require waiting for render
|
||||
'scrollIntoView',
|
||||
'scrollTo',
|
||||
]
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'require screenshots to be preceded by an assertion',
|
||||
category: 'Possible Errors',
|
||||
recommended: false,
|
||||
url: 'https://github.com/cypress-io/eslint-plugin-cypress/blob/master/docs/rules/assertion-before-screenshot.md',
|
||||
},
|
||||
schema: [],
|
||||
messages: {
|
||||
unexpected: 'Make an assertion on the page state before taking a screenshot',
|
||||
},
|
||||
},
|
||||
create (context) {
|
||||
return {
|
||||
CallExpression (node) {
|
||||
if (isCallingCyScreenshot(node) && !isPreviousAnAssertion(node)) {
|
||||
context.report({ node, messageId: 'unexpected' })
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
function isRootCypress (node) {
|
||||
while (node.type === 'CallExpression') {
|
||||
if (node.callee.type !== 'MemberExpression') return false
|
||||
|
||||
if (node.callee.object.type === 'Identifier' &&
|
||||
node.callee.object.name === 'cy') {
|
||||
return true
|
||||
}
|
||||
|
||||
node = node.callee.object
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
function getPreviousInChain (node) {
|
||||
return node.type === 'CallExpression' &&
|
||||
node.callee.type === 'MemberExpression' &&
|
||||
node.callee.object.type === 'CallExpression' &&
|
||||
node.callee.object.callee.type === 'MemberExpression' &&
|
||||
node.callee.object.callee.property.type === 'Identifier' &&
|
||||
node.callee.object.callee.property.name
|
||||
}
|
||||
|
||||
function getCallExpressionCypressCommand (node) {
|
||||
return isRootCypress(node) &&
|
||||
node.callee.property.type === 'Identifier' &&
|
||||
node.callee.property.name
|
||||
}
|
||||
|
||||
function isCallingCyScreenshot (node) {
|
||||
return getCallExpressionCypressCommand(node) === 'screenshot'
|
||||
}
|
||||
|
||||
function getPreviousCypressCommand (node) {
|
||||
const previousInChain = getPreviousInChain(node)
|
||||
|
||||
if (previousInChain) {
|
||||
return previousInChain
|
||||
}
|
||||
|
||||
while (node.parent && !node.parent.body) {
|
||||
node = node.parent
|
||||
}
|
||||
|
||||
if (!node.parent || !node.parent.body) return null
|
||||
|
||||
const body = node.parent.body.type === 'BlockStatement' ? node.parent.body.body : node.parent.body
|
||||
|
||||
const index = body.indexOf(node)
|
||||
|
||||
// in the case of a function declaration it won't be found
|
||||
if (index < 0) return null
|
||||
|
||||
if (index === 0) return getPreviousCypressCommand(node.parent)
|
||||
|
||||
const previousStatement = body[index - 1]
|
||||
|
||||
if (previousStatement.type !== 'ExpressionStatement' ||
|
||||
previousStatement.expression.type !== 'CallExpression') {
|
||||
return null
|
||||
}
|
||||
|
||||
return getCallExpressionCypressCommand(previousStatement.expression)
|
||||
}
|
||||
|
||||
function isPreviousAnAssertion (node) {
|
||||
const previousCypressCommand = getPreviousCypressCommand(node)
|
||||
|
||||
return assertionCommands.indexOf(previousCypressCommand) >= 0
|
||||
}
|
||||
68
node_modules/eslint-plugin-cypress/lib/rules/no-assigning-return-values.js
generated
vendored
Normal file
68
node_modules/eslint-plugin-cypress/lib/rules/no-assigning-return-values.js
generated
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
'use strict'
|
||||
|
||||
// safely get nested object property
|
||||
function get (obj, propertyString = '') {
|
||||
const properties = propertyString.split('.')
|
||||
|
||||
for (let i = 0; i < properties.length; i++) {
|
||||
const value = (obj || {})[properties[i]]
|
||||
|
||||
if (value == null) return value
|
||||
|
||||
obj = value
|
||||
}
|
||||
|
||||
return obj
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'disallow assigning return values of `cy` calls',
|
||||
category: 'Possible Errors',
|
||||
recommended: true,
|
||||
url: 'https://github.com/cypress-io/eslint-plugin-cypress/blob/master/docs/rules/no-assigning-return-values.md',
|
||||
},
|
||||
schema: [],
|
||||
messages: {
|
||||
unexpected: 'Do not assign the return value of a Cypress command',
|
||||
},
|
||||
},
|
||||
create (context) {
|
||||
return {
|
||||
VariableDeclaration (node) {
|
||||
if (node.declarations.some(isCypressCommandDeclaration)) {
|
||||
context.report({ node, messageId: 'unexpected' })
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
const allowedCommands = {
|
||||
now: true,
|
||||
spy: true,
|
||||
state: true,
|
||||
stub: true,
|
||||
}
|
||||
|
||||
function isCypressCommandDeclaration (declarator) {
|
||||
let object = get(declarator, 'init.callee.object')
|
||||
|
||||
if (!object) return
|
||||
|
||||
while (object.callee) {
|
||||
object = object.callee.object
|
||||
|
||||
if (!object) return
|
||||
}
|
||||
|
||||
const commandName = get(declarator, 'init.callee.property.name')
|
||||
|
||||
const parent = get(object, 'parent.property.name') || get(declarator, 'id.name')
|
||||
|
||||
if (commandName && (allowedCommands[commandName] || allowedCommands[parent])) return
|
||||
|
||||
return object.name === 'cy'
|
||||
}
|
||||
53
node_modules/eslint-plugin-cypress/lib/rules/no-async-before.js
generated
vendored
Normal file
53
node_modules/eslint-plugin-cypress/lib/rules/no-async-before.js
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
'use strict'
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'disallow using `async`/`await` in Cypress `before` methods',
|
||||
category: 'Possible Errors',
|
||||
recommended: true,
|
||||
url: 'https://github.com/cypress-io/eslint-plugin-cypress/blob/master/docs/rules/no-async-before.md',
|
||||
},
|
||||
schema: [],
|
||||
messages: {
|
||||
unexpected: 'Avoid using async functions with Cypress before / beforeEach functions',
|
||||
},
|
||||
},
|
||||
|
||||
create (context) {
|
||||
function isBeforeBlock (callExpressionNode) {
|
||||
const { type, name } = callExpressionNode.callee
|
||||
|
||||
return type === 'Identifier'
|
||||
&& name === 'before' || name === 'beforeEach'
|
||||
}
|
||||
|
||||
function isBeforeAsync (node) {
|
||||
return node.arguments
|
||||
&& node.arguments.length >= 2
|
||||
&& node.arguments[1].async === true
|
||||
}
|
||||
const sourceCode = context.sourceCode ?? context.getSourceCode()
|
||||
|
||||
return {
|
||||
Identifier (node) {
|
||||
if (node.name === 'cy' || node.name === 'Cypress') {
|
||||
const ancestors = sourceCode.getAncestors
|
||||
? sourceCode.getAncestors(node)
|
||||
: context.getAncestors()
|
||||
const asyncTestBlocks = ancestors
|
||||
.filter((n) => n.type === 'CallExpression')
|
||||
.filter(isBeforeBlock)
|
||||
.filter(isBeforeAsync)
|
||||
|
||||
if (asyncTestBlocks.length >= 1) {
|
||||
asyncTestBlocks.forEach((node) => {
|
||||
context.report({ node, messageId: 'unexpected' })
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
53
node_modules/eslint-plugin-cypress/lib/rules/no-async-tests.js
generated
vendored
Normal file
53
node_modules/eslint-plugin-cypress/lib/rules/no-async-tests.js
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
'use strict'
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'disallow using `async`/`await` in Cypress test cases',
|
||||
category: 'Possible Errors',
|
||||
recommended: true,
|
||||
url: 'https://github.com/cypress-io/eslint-plugin-cypress/blob/master/docs/rules/no-async-tests.md',
|
||||
},
|
||||
schema: [],
|
||||
messages: {
|
||||
unexpected: 'Avoid using async functions with Cypress tests',
|
||||
},
|
||||
},
|
||||
|
||||
create (context) {
|
||||
function isTestBlock (callExpressionNode) {
|
||||
const { type, name } = callExpressionNode.callee
|
||||
|
||||
return type === 'Identifier'
|
||||
&& name === 'it' || name === 'test'
|
||||
}
|
||||
|
||||
function isTestAsync (node) {
|
||||
return node.arguments
|
||||
&& node.arguments.length >= 2
|
||||
&& node.arguments[1].async === true
|
||||
}
|
||||
const sourceCode = context.sourceCode ?? context.getSourceCode()
|
||||
|
||||
return {
|
||||
Identifier (node) {
|
||||
if (node.name === 'cy' || node.name === 'Cypress') {
|
||||
const ancestors = sourceCode.getAncestors
|
||||
? sourceCode.getAncestors(node)
|
||||
: context.getAncestors()
|
||||
const asyncTestBlocks = ancestors
|
||||
.filter((n) => n.type === 'CallExpression')
|
||||
.filter(isTestBlock)
|
||||
.filter(isTestAsync)
|
||||
|
||||
if (asyncTestBlocks.length >= 1) {
|
||||
asyncTestBlocks.forEach((node) => {
|
||||
context.report({ node, messageId: 'unexpected' })
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
61
node_modules/eslint-plugin-cypress/lib/rules/no-debug.js
generated
vendored
Normal file
61
node_modules/eslint-plugin-cypress/lib/rules/no-debug.js
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
'use strict'
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Rule Definition
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description: 'disallow using `cy.debug()` calls',
|
||||
category: 'Possible Errors',
|
||||
recommended: false,
|
||||
url: 'https://github.com/cypress-io/eslint-plugin-cypress/blob/master/docs/rules/no-debug.md',
|
||||
},
|
||||
fixable: null, // or "code" or "whitespace"
|
||||
schema: [],
|
||||
messages: {
|
||||
unexpected: 'Do not use cy.debug command',
|
||||
},
|
||||
},
|
||||
|
||||
create (context) {
|
||||
|
||||
// variables should be defined here
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Helpers
|
||||
//----------------------------------------------------------------------
|
||||
function isCallingDebug (node) {
|
||||
return node.callee &&
|
||||
node.callee.property &&
|
||||
node.callee.property.type === 'Identifier' &&
|
||||
node.callee.property.name === 'debug'
|
||||
}
|
||||
|
||||
function isCypressCall (node) {
|
||||
if (!node.callee || node.callee.type !== 'MemberExpression') {
|
||||
return false;
|
||||
}
|
||||
if (node.callee.object.type === 'Identifier' && node.callee.object.name === 'cy') {
|
||||
return true;
|
||||
}
|
||||
return isCypressCall(node.callee.object);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Public
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
return {
|
||||
|
||||
CallExpression (node) {
|
||||
if (isCypressCall(node) && isCallingDebug(node)) {
|
||||
context.report({ node, messageId: 'unexpected' })
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
},
|
||||
}
|
||||
80
node_modules/eslint-plugin-cypress/lib/rules/no-force.js
generated
vendored
Normal file
80
node_modules/eslint-plugin-cypress/lib/rules/no-force.js
generated
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
'use strict'
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Rule Definition
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description: 'disallow using `force: true` with action commands',
|
||||
category: 'Possible Errors',
|
||||
recommended: false,
|
||||
url: 'https://github.com/cypress-io/eslint-plugin-cypress/blob/master/docs/rules/no-force.md',
|
||||
},
|
||||
fixable: null, // or "code" or "whitespace"
|
||||
schema: [],
|
||||
messages: {
|
||||
unexpected: 'Do not use force on click and type calls',
|
||||
},
|
||||
},
|
||||
|
||||
create (context) {
|
||||
|
||||
// variables should be defined here
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Helpers
|
||||
//----------------------------------------------------------------------
|
||||
function isCallingClickOrType (node) {
|
||||
const allowedMethods = ['click', 'dblclick', 'type', 'trigger', 'check', 'rightclick', 'focus', 'select']
|
||||
|
||||
return node.property && node.property.type === 'Identifier' &&
|
||||
allowedMethods.includes(node.property.name)
|
||||
}
|
||||
|
||||
function isCypressCall (node) {
|
||||
return node.callee.type === 'MemberExpression' &&
|
||||
node.callee.object.type === 'Identifier' &&
|
||||
node.callee.object.name === 'cy'
|
||||
}
|
||||
|
||||
function hasOptionForce (node) {
|
||||
|
||||
return node.arguments && node.arguments.length &&
|
||||
node.arguments.some((arg) => {
|
||||
return arg.type === 'ObjectExpression' && arg.properties.some((propNode) => propNode.key && propNode.key.name === 'force')
|
||||
})
|
||||
}
|
||||
|
||||
function deepCheck (node, checkFunc) {
|
||||
let currentNode = node
|
||||
|
||||
while (currentNode.parent) {
|
||||
|
||||
if (checkFunc(currentNode.parent)) {
|
||||
return true
|
||||
}
|
||||
|
||||
currentNode = currentNode.parent
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Public
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
return {
|
||||
|
||||
CallExpression (node) {
|
||||
if (isCypressCall(node) && deepCheck(node, isCallingClickOrType) && deepCheck(node, hasOptionForce)) {
|
||||
context.report({ node, messageId: 'unexpected' })
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
},
|
||||
}
|
||||
61
node_modules/eslint-plugin-cypress/lib/rules/no-pause.js
generated
vendored
Normal file
61
node_modules/eslint-plugin-cypress/lib/rules/no-pause.js
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
'use strict'
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Rule Definition
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description: 'disallow using `cy.pause()` calls',
|
||||
category: 'Possible Errors',
|
||||
recommended: false,
|
||||
url: 'https://github.com/cypress-io/eslint-plugin-cypress/blob/master/docs/rules/no-pause.md',
|
||||
},
|
||||
fixable: null, // or "code" or "whitespace"
|
||||
schema: [],
|
||||
messages: {
|
||||
unexpected: 'Do not use cy.pause command',
|
||||
},
|
||||
},
|
||||
|
||||
create (context) {
|
||||
|
||||
// variables should be defined here
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Helpers
|
||||
//----------------------------------------------------------------------
|
||||
function isCallingPause (node) {
|
||||
return node.callee &&
|
||||
node.callee.property &&
|
||||
node.callee.property.type === 'Identifier' &&
|
||||
node.callee.property.name === 'pause'
|
||||
}
|
||||
|
||||
function isCypressCall (node) {
|
||||
if (!node.callee || node.callee.type !== 'MemberExpression') {
|
||||
return false;
|
||||
}
|
||||
if (node.callee.object.type === 'Identifier' && node.callee.object.name === 'cy') {
|
||||
return true;
|
||||
}
|
||||
return isCypressCall(node.callee.object);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Public
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
return {
|
||||
|
||||
CallExpression (node) {
|
||||
if (isCypressCall(node) && isCallingPause(node)) {
|
||||
context.report({ node, messageId: 'unexpected' })
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
},
|
||||
}
|
||||
91
node_modules/eslint-plugin-cypress/lib/rules/no-unnecessary-waiting.js
generated
vendored
Normal file
91
node_modules/eslint-plugin-cypress/lib/rules/no-unnecessary-waiting.js
generated
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
'use strict'
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'disallow waiting for arbitrary time periods',
|
||||
category: 'Possible Errors',
|
||||
recommended: true,
|
||||
url: 'https://github.com/cypress-io/eslint-plugin-cypress/blob/master/docs/rules/no-unnecessary-waiting.md',
|
||||
},
|
||||
schema: [],
|
||||
messages: {
|
||||
unexpected: 'Do not wait for arbitrary time periods',
|
||||
},
|
||||
},
|
||||
create (context) {
|
||||
const sourceCode = context.sourceCode ?? context.getSourceCode()
|
||||
|
||||
return {
|
||||
CallExpression (node) {
|
||||
if (isCallingCyWait(node)) {
|
||||
const scope = sourceCode.getScope
|
||||
? sourceCode.getScope(node)
|
||||
: context.getScope()
|
||||
|
||||
if (isIdentifierNumberConstArgument(node, scope) || isNumberArgument(node)) {
|
||||
context.report({ node, messageId: 'unexpected' })
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
function nodeIsCalledByCy (node) {
|
||||
if (node.type === 'Identifier' && node.name === 'cy') return true
|
||||
|
||||
if (typeof node.callee === 'undefined' || typeof node.callee.object === 'undefined') {
|
||||
return false
|
||||
}
|
||||
|
||||
return nodeIsCalledByCy(node.callee.object)
|
||||
}
|
||||
|
||||
function isCallingCyWait (node) {
|
||||
return node.callee.type === 'MemberExpression' &&
|
||||
nodeIsCalledByCy(node) &&
|
||||
node.callee.property.type === 'Identifier' &&
|
||||
node.callee.property.name === 'wait'
|
||||
}
|
||||
|
||||
function isNumberArgument (node) {
|
||||
return node.arguments.length > 0 &&
|
||||
node.arguments[0].type === 'Literal' &&
|
||||
typeof (node.arguments[0].value) === 'number'
|
||||
}
|
||||
|
||||
function isIdentifierNumberConstArgument (node, scope) {
|
||||
if (node.arguments.length === 0) return false
|
||||
|
||||
if (node.arguments[0].type !== 'Identifier') return false
|
||||
|
||||
const identifier = node.arguments[0]
|
||||
const resolvedIdentifier = scope.references.find((ref) => ref.identifier === identifier).resolved
|
||||
const definition = resolvedIdentifier.defs[0]
|
||||
const isVariable = definition.type === 'Variable'
|
||||
|
||||
// const amount = 1000 or const amount = '@alias'
|
||||
// cy.wait(amount)
|
||||
if (isVariable) {
|
||||
if (!definition.node.init) return false
|
||||
|
||||
return typeof definition.node.init.value === 'number'
|
||||
}
|
||||
|
||||
// import { WAIT } from './constants'
|
||||
// cy.wait(WAIT)
|
||||
// we don't know if WAIT is a number or alias '@someRequest', so don't fail
|
||||
if (definition.type === 'ImportBinding') return false
|
||||
|
||||
const param = definition.node.params[definition.index]
|
||||
|
||||
// function wait (amount) { cy.wait(amount) }
|
||||
// we can't know the type of value, so don't fail
|
||||
if (!param || param.type !== 'AssignmentPattern') return false
|
||||
|
||||
// function wait (amount = 1) { cy.wait(amount) } or
|
||||
// function wait (amount = '@alias') { cy.wait(amount) }
|
||||
return typeof param.right.value === 'number'
|
||||
}
|
||||
49
node_modules/eslint-plugin-cypress/lib/rules/require-data-selectors.js
generated
vendored
Normal file
49
node_modules/eslint-plugin-cypress/lib/rules/require-data-selectors.js
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
'use strict'
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description: 'require `data-*` attribute selectors',
|
||||
category: 'Possible Errors',
|
||||
recommended: false,
|
||||
url: 'https://github.com/cypress-io/eslint-plugin-cypress/blob/master/docs/rules/require-data-selectors.md',
|
||||
},
|
||||
schema: [],
|
||||
messages: {
|
||||
unexpected: 'use data-* attribute selectors instead of classes or tag names',
|
||||
},
|
||||
},
|
||||
|
||||
create (context) {
|
||||
return {
|
||||
CallExpression (node) {
|
||||
if (isCallingCyGet(node) && !isDataArgument(node)) {
|
||||
context.report({ node, messageId: 'unexpected' })
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
function isCallingCyGet (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 === 'get'
|
||||
}
|
||||
|
||||
function isDataArgument (node) {
|
||||
return node.arguments.length > 0 &&
|
||||
(
|
||||
(node.arguments[0].type === 'Literal' && isAliasOrDataSelector(String(node.arguments[0].value))) ||
|
||||
(node.arguments[0].type === 'TemplateLiteral' && isAliasOrDataSelector(String(node.arguments[0].quasis[0].value.cooked)))
|
||||
)
|
||||
}
|
||||
|
||||
function isAliasOrDataSelector (selector) {
|
||||
return ['[data-', '@'].some(function (validValue) {
|
||||
return selector.startsWith(validValue)
|
||||
})
|
||||
}
|
||||
143
node_modules/eslint-plugin-cypress/lib/rules/unsafe-to-chain-command.js
generated
vendored
Normal file
143
node_modules/eslint-plugin-cypress/lib/rules/unsafe-to-chain-command.js
generated
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
'use strict'
|
||||
|
||||
const { basename } = require('path')
|
||||
|
||||
const NAME = basename(__dirname)
|
||||
const DESCRIPTION = 'disallow actions within chains'
|
||||
|
||||
/**
|
||||
* Commands listed in the documentation with text: 'It is unsafe to chain further commands that rely on the subject after xxx.'
|
||||
* 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}
|
||||
* for more information.
|
||||
*
|
||||
* @type {string[]}
|
||||
*/
|
||||
const unsafeToChainActions = [
|
||||
'blur',
|
||||
'clear',
|
||||
'click',
|
||||
'check',
|
||||
'dblclick',
|
||||
'each',
|
||||
'focus',
|
||||
'rightclick',
|
||||
'screenshot',
|
||||
'scrollIntoView',
|
||||
'scrollTo',
|
||||
'select',
|
||||
'selectFile',
|
||||
'spread',
|
||||
'submit',
|
||||
'type',
|
||||
'trigger',
|
||||
'uncheck',
|
||||
'within',
|
||||
]
|
||||
|
||||
/**
|
||||
* @type {import('eslint').Rule.RuleMetaData['schema']}
|
||||
*/
|
||||
const schema = {
|
||||
title: NAME,
|
||||
description: DESCRIPTION,
|
||||
type: 'object',
|
||||
properties: {
|
||||
methods: {
|
||||
type: 'array',
|
||||
description:
|
||||
'An additional list of methods to check for unsafe chaining.',
|
||||
default: [],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('eslint').Rule.RuleContext} context
|
||||
* @returns {Record<string, any>}
|
||||
*/
|
||||
const getDefaultOptions = (context) => {
|
||||
return Object.entries(schema.properties).reduce((acc, [key, value]) => {
|
||||
if (!(value.default in value)) return acc
|
||||
|
||||
return {
|
||||
...acc,
|
||||
[key]: value.default,
|
||||
}
|
||||
}, context.options[0] || {})
|
||||
}
|
||||
|
||||
/** @type {import('eslint').Rule.RuleModule} */
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: DESCRIPTION,
|
||||
category: 'Possible Errors',
|
||||
recommended: true,
|
||||
url: 'https://github.com/cypress-io/eslint-plugin-cypress/blob/master/docs/rules/unsafe-to-chain-command.md',
|
||||
},
|
||||
schema: [schema],
|
||||
messages: {
|
||||
unexpected:
|
||||
'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.',
|
||||
},
|
||||
},
|
||||
create (context) {
|
||||
const { methods } = getDefaultOptions(context)
|
||||
|
||||
return {
|
||||
CallExpression (node) {
|
||||
if (
|
||||
isRootCypress(node) &&
|
||||
isActionUnsafeToChain(node, methods) &&
|
||||
node.parent.type === 'MemberExpression'
|
||||
) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'unexpected',
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('estree').Node} node
|
||||
* @returns {boolean}
|
||||
*/
|
||||
const isRootCypress = (node) => {
|
||||
if (
|
||||
node.type !== 'CallExpression' ||
|
||||
node.callee.type !== 'MemberExpression'
|
||||
) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (
|
||||
node.callee.object.type === 'Identifier' &&
|
||||
node.callee.object.name === 'cy'
|
||||
) {
|
||||
return true
|
||||
}
|
||||
|
||||
return isRootCypress(node.callee.object)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('estree').Node} node
|
||||
* @param {(string | RegExp)[]} additionalMethods
|
||||
*/
|
||||
const isActionUnsafeToChain = (node, additionalMethods = []) => {
|
||||
const unsafeActionsRegex = new RegExp([
|
||||
...unsafeToChainActions.map((action) => `^${action}$`),
|
||||
...additionalMethods.map((method) => method instanceof RegExp ? method.source : method),
|
||||
].join('|'))
|
||||
|
||||
return (
|
||||
node.callee &&
|
||||
node.callee.property &&
|
||||
node.callee.property.type === 'Identifier' &&
|
||||
unsafeActionsRegex.test(node.callee.property.name)
|
||||
)
|
||||
}
|
||||
2972
node_modules/eslint-plugin-cypress/node_modules/globals/globals.json
generated
vendored
Normal file
2972
node_modules/eslint-plugin-cypress/node_modules/globals/globals.json
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3069
node_modules/eslint-plugin-cypress/node_modules/globals/index.d.ts
generated
vendored
Normal file
3069
node_modules/eslint-plugin-cypress/node_modules/globals/index.d.ts
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
2
node_modules/eslint-plugin-cypress/node_modules/globals/index.js
generated
vendored
Normal file
2
node_modules/eslint-plugin-cypress/node_modules/globals/index.js
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
'use strict';
|
||||
module.exports = require('./globals.json');
|
||||
9
node_modules/eslint-plugin-cypress/node_modules/globals/license
generated
vendored
Normal file
9
node_modules/eslint-plugin-cypress/node_modules/globals/license
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
98
node_modules/eslint-plugin-cypress/node_modules/globals/package.json
generated
vendored
Normal file
98
node_modules/eslint-plugin-cypress/node_modules/globals/package.json
generated
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
{
|
||||
"name": "globals",
|
||||
"version": "15.12.0",
|
||||
"description": "Global identifiers from different JavaScript environments",
|
||||
"license": "MIT",
|
||||
"repository": "sindresorhus/globals",
|
||||
"funding": "https://github.com/sponsors/sindresorhus",
|
||||
"author": {
|
||||
"name": "Sindre Sorhus",
|
||||
"email": "sindresorhus@gmail.com",
|
||||
"url": "https://sindresorhus.com"
|
||||
},
|
||||
"sideEffects": false,
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "npm run build && xo && ava && tsd",
|
||||
"prepare": "npm run build",
|
||||
"update": "node scripts/update.mjs",
|
||||
"update:browser": "node scripts/update.mjs --environment=browser",
|
||||
"update:builtin": "node scripts/update.mjs --environment=builtin",
|
||||
"update:nodeBuiltin": "node scripts/update.mjs --environment=nodeBuiltin",
|
||||
"update:worker": "node scripts/update.mjs --environment=worker",
|
||||
"update:shelljs": "node scripts/update.mjs --environment=shelljs",
|
||||
"update:jest": "node scripts/update.mjs --environment=jest",
|
||||
"build": "run-s build:data build:types",
|
||||
"build:data": "node scripts/generate-data.mjs",
|
||||
"build:types": "node scripts/generate-types.mjs"
|
||||
},
|
||||
"files": [
|
||||
"index.js",
|
||||
"index.d.ts",
|
||||
"globals.json"
|
||||
],
|
||||
"keywords": [
|
||||
"globals",
|
||||
"global",
|
||||
"identifiers",
|
||||
"variables",
|
||||
"vars",
|
||||
"jshint",
|
||||
"eslint",
|
||||
"environments"
|
||||
],
|
||||
"devDependencies": {
|
||||
"ava": "^6.1.3",
|
||||
"cheerio": "^1.0.0-rc.12",
|
||||
"eslint-plugin-jest": "^28.8.3",
|
||||
"execa": "^9.4.0",
|
||||
"get-port": "^7.1.0",
|
||||
"npm-run-all2": "^6.2.3",
|
||||
"outdent": "^0.8.0",
|
||||
"puppeteer": "^23.4.1",
|
||||
"shelljs": "^0.8.5",
|
||||
"tsd": "^0.31.2",
|
||||
"type-fest": "^4.26.1",
|
||||
"xo": "^0.59.3"
|
||||
},
|
||||
"xo": {
|
||||
"rules": {
|
||||
"unicorn/prefer-module": "off"
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": [
|
||||
"data/*.mjs"
|
||||
],
|
||||
"rules": {
|
||||
"import/no-anonymous-default-export": "off",
|
||||
"camelcase": "off",
|
||||
"unicorn/filename-case": [
|
||||
"error",
|
||||
{
|
||||
"cases": {
|
||||
"camelCase": true,
|
||||
"kebabCase": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"scripts/*.mjs"
|
||||
],
|
||||
"rules": {
|
||||
"n/no-unsupported-features/node-builtins": "off"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"tsd": {
|
||||
"compilerOptions": {
|
||||
"resolveJsonModule": true
|
||||
}
|
||||
}
|
||||
}
|
||||
42
node_modules/eslint-plugin-cypress/node_modules/globals/readme.md
generated
vendored
Normal file
42
node_modules/eslint-plugin-cypress/node_modules/globals/readme.md
generated
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
# globals
|
||||
|
||||
> Global identifiers from different JavaScript environments
|
||||
|
||||
It's just a [JSON file](globals.json), so you can use it in any environment.
|
||||
|
||||
This package is used by ESLint 8 and earlier. For ESLint 9 and later, you should depend on this package directly in [your ESLint config](https://eslint.org/docs/latest/use/configure/language-options#predefined-global-variables).
|
||||
|
||||
## Install
|
||||
|
||||
```sh
|
||||
npm install globals
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
import globals from 'globals';
|
||||
|
||||
console.log(globals.browser);
|
||||
/*
|
||||
{
|
||||
addEventListener: false,
|
||||
applicationCache: false,
|
||||
ArrayBuffer: false,
|
||||
atob: false,
|
||||
…
|
||||
}
|
||||
*/
|
||||
```
|
||||
|
||||
Each global is given a value of `true` or `false`. A value of `true` indicates that the variable may be overwritten. A value of `false` indicates that the variable should be considered read-only. This information is used by static analysis tools to flag incorrect behavior. We assume all variables should be `false` unless we hear otherwise.
|
||||
|
||||
For Node.js this package provides two sets of globals:
|
||||
|
||||
- `globals.nodeBuiltin`: Globals available to all code running in Node.js.
|
||||
These will usually be available as properties on the `globalThis` object and include `process`, `Buffer`, but not CommonJS arguments like `require`.
|
||||
See: https://nodejs.org/api/globals.html
|
||||
- `globals.node`: A combination of the globals from `nodeBuiltin` plus all CommonJS arguments ("CommonJS module scope").
|
||||
See: https://nodejs.org/api/modules.html#modules_the_module_scope
|
||||
|
||||
When analyzing code that is known to run outside of a CommonJS wrapper, for example, JavaScript modules, `nodeBuiltin` can find accidental CommonJS references.
|
||||
50
node_modules/eslint-plugin-cypress/package.json
generated
vendored
Normal file
50
node_modules/eslint-plugin-cypress/package.json
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"name": "eslint-plugin-cypress",
|
||||
"version": "4.1.0",
|
||||
"description": "An ESLint plugin for projects using Cypress",
|
||||
"main": "legacy.js",
|
||||
"exports": {
|
||||
".": "./legacy.js",
|
||||
"./flat": "./lib/flat.js"
|
||||
},
|
||||
"author": "Cypress-io",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"eslint",
|
||||
"eslintplugin",
|
||||
"cypress"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/cypress-io/eslint-plugin-cypress.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/cypress-io/eslint-plugin-cypress/issues"
|
||||
},
|
||||
"homepage": "https://github.com/cypress-io/eslint-plugin-cypress#readme",
|
||||
"peerDependencies": {
|
||||
"eslint": ">=9"
|
||||
},
|
||||
"dependencies": {
|
||||
"globals": "^15.11.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^9.13.0",
|
||||
"eslint-plugin-eslint-plugin": "^6.3.1",
|
||||
"eslint-plugin-mocha": "^10.5.0",
|
||||
"eslint-plugin-n": "^17.11.1",
|
||||
"husky": "^9.1.6",
|
||||
"jest": "^29.7.0",
|
||||
"semantic-release": "24.2.0"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint \"*.js\" \"**/**/*.js\"",
|
||||
"lint-fix": "npm run lint -- --fix",
|
||||
"semantic-release": "semantic-release",
|
||||
"start": "npm run test-watch",
|
||||
"test": "jest",
|
||||
"test:legacy": "jest --config jest.config-legacy.js",
|
||||
"test-watch": "jest --watchAll",
|
||||
"prepare": "husky"
|
||||
}
|
||||
}
|
||||
26
node_modules/eslint-plugin-cypress/tests-legacy/config.js
generated
vendored
Normal file
26
node_modules/eslint-plugin-cypress/tests-legacy/config.js
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
/* global describe, it, expect */
|
||||
'use strict'
|
||||
|
||||
const globals = require('globals')
|
||||
const config = require('../legacy.js')
|
||||
|
||||
describe('environments globals', () => {
|
||||
const env = config.environments.globals
|
||||
|
||||
it('should not mutate globals', () => {
|
||||
expect(globals.browser).not.toHaveProperty('cy')
|
||||
expect(globals.mocha).not.toHaveProperty('cy')
|
||||
})
|
||||
|
||||
it('should include other globals', () => {
|
||||
expect(env.globals).toEqual(expect.objectContaining(globals.browser))
|
||||
expect(env.globals).toEqual(expect.objectContaining(globals.mocha))
|
||||
})
|
||||
|
||||
it('should include cypress globals', () => {
|
||||
expect(env.globals).toEqual(expect.objectContaining({
|
||||
cy: false,
|
||||
Cypress: false,
|
||||
}))
|
||||
})
|
||||
})
|
||||
35
node_modules/eslint-plugin-cypress/tests-legacy/lib/rules/assertion-before-screenshot.js
generated
vendored
Normal file
35
node_modules/eslint-plugin-cypress/tests-legacy/lib/rules/assertion-before-screenshot.js
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
'use strict'
|
||||
|
||||
const rule = require('../../../lib/rules/assertion-before-screenshot')
|
||||
const RuleTester = require('eslint').RuleTester
|
||||
|
||||
const ruleTester = new RuleTester()
|
||||
|
||||
const errors = [{ messageId: 'unexpected' }]
|
||||
const parserOptions = { ecmaVersion: 6 }
|
||||
|
||||
ruleTester.run('assertion-before-screenshot', rule, {
|
||||
valid: [
|
||||
{ code: 'cy.get(".some-element"); cy.screenshot();', parserOptions },
|
||||
{ code: 'cy.get(".some-element").should("exist").screenshot();', parserOptions },
|
||||
{ code: 'cy.get(".some-element").should("exist").screenshot().click()', parserOptions, errors },
|
||||
{ code: 'cy.get(".some-element").should("exist"); if(true) cy.screenshot();', parserOptions },
|
||||
{ code: 'if(true) { cy.get(".some-element").should("exist"); cy.screenshot(); }', parserOptions },
|
||||
{ code: 'cy.get(".some-element").should("exist"); if(true) { cy.screenshot(); }', parserOptions },
|
||||
{ code: 'const a = () => { cy.get(".some-element").should("exist"); cy.screenshot(); }', parserOptions, errors },
|
||||
{ code: 'cy.get(".some-element").should("exist").and("be.visible"); cy.screenshot();', parserOptions },
|
||||
{ code: 'cy.get(".some-element").contains("Text"); cy.screenshot();', parserOptions },
|
||||
],
|
||||
|
||||
invalid: [
|
||||
{ code: 'cy.screenshot()', parserOptions, errors },
|
||||
{ code: 'cy.visit("somepage"); cy.screenshot();', parserOptions, errors },
|
||||
{ code: 'cy.custom(); cy.screenshot()', parserOptions, errors },
|
||||
{ code: 'cy.get(".some-element").click(); cy.screenshot()', parserOptions, errors },
|
||||
{ code: 'cy.get(".some-element").click().screenshot()', parserOptions, errors },
|
||||
{ code: 'if(true) { cy.get(".some-element").click(); cy.screenshot(); }', parserOptions, errors },
|
||||
{ code: 'cy.get(".some-element").click(); if(true) { cy.screenshot(); }', parserOptions, errors },
|
||||
{ code: 'cy.get(".some-element"); function a() { cy.screenshot(); }', parserOptions, errors },
|
||||
{ code: 'cy.get(".some-element"); const a = () => { cy.screenshot(); }', parserOptions, errors },
|
||||
],
|
||||
})
|
||||
38
node_modules/eslint-plugin-cypress/tests-legacy/lib/rules/no-assigning-return-values.js
generated
vendored
Normal file
38
node_modules/eslint-plugin-cypress/tests-legacy/lib/rules/no-assigning-return-values.js
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
'use strict'
|
||||
|
||||
const rule = require('../../../lib/rules/no-assigning-return-values')
|
||||
const RuleTester = require('eslint').RuleTester
|
||||
|
||||
const ruleTester = new RuleTester()
|
||||
|
||||
const errors = [{ messageId: 'unexpected' }]
|
||||
const parserOptions = { ecmaVersion: 6 }
|
||||
|
||||
ruleTester.run('no-assigning-return-values', rule, {
|
||||
valid: [
|
||||
{ code: 'var foo = true;', parserOptions },
|
||||
{ code: 'let foo = true;', parserOptions },
|
||||
{ code: 'const foo = true;', parserOptions },
|
||||
{ code: 'const foo = bar();', parserOptions },
|
||||
{ code: 'const foo = bar().baz();', parserOptions },
|
||||
{ code: 'const spy = cy.spy();', parserOptions },
|
||||
{ code: 'const spy = cy.spy().as();', parserOptions },
|
||||
{ code: 'const stub = cy.stub();', parserOptions },
|
||||
{ code: 'const result = cy.now();', parserOptions },
|
||||
{ code: 'const state = cy.state();', parserOptions },
|
||||
{ code: 'cy.get("foo");', parserOptions },
|
||||
{ code: 'cy.contains("foo").click();', parserOptions },
|
||||
],
|
||||
|
||||
invalid: [
|
||||
{ code: 'let a = cy.get("foo")', parserOptions, errors },
|
||||
{ code: 'const a = cy.get("foo")', parserOptions, errors },
|
||||
{ code: 'var a = cy.get("foo")', parserOptions, errors },
|
||||
|
||||
{ code: 'let a = cy.contains("foo")', parserOptions, errors },
|
||||
{ code: 'let a = cy.window()', parserOptions, errors },
|
||||
{ code: 'let a = cy.wait("@something")', parserOptions, errors },
|
||||
|
||||
{ code: 'let a = cy.contains("foo").click()', parserOptions, errors },
|
||||
],
|
||||
})
|
||||
25
node_modules/eslint-plugin-cypress/tests-legacy/lib/rules/no-async-before.js
generated
vendored
Normal file
25
node_modules/eslint-plugin-cypress/tests-legacy/lib/rules/no-async-before.js
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
'use strict'
|
||||
|
||||
const rule = require('../../../lib/rules/no-async-before')
|
||||
const RuleTester = require('eslint').RuleTester
|
||||
|
||||
const ruleTester = new RuleTester()
|
||||
|
||||
const errors = [{ messageId: 'unexpected' }]
|
||||
// async functions are an ES2017 feature
|
||||
const parserOptions = { ecmaVersion: 8 }
|
||||
|
||||
ruleTester.run('no-async-before', rule, {
|
||||
valid: [
|
||||
{ code: 'before(\'a before case\', () => { cy.get(\'.someClass\'); })', parserOptions },
|
||||
{ code: 'before(\'a before case\', async () => { await somethingAsync(); })', parserOptions },
|
||||
{ code: 'async function nonTestFn () { return await somethingAsync(); }', parserOptions },
|
||||
{ code: 'const nonTestArrowFn = async () => { await somethingAsync(); }', parserOptions },
|
||||
],
|
||||
invalid: [
|
||||
{ code: 'before(\'a test case\', async () => { cy.get(\'.someClass\'); })', parserOptions, errors },
|
||||
{ code: 'beforeEach(\'a test case\', async () => { cy.get(\'.someClass\'); })', parserOptions, errors },
|
||||
{ code: 'before(\'a test case\', async function () { cy.get(\'.someClass\'); })', parserOptions, errors },
|
||||
{ code: 'beforeEach(\'a test case\', async function () { cy.get(\'.someClass\'); })', parserOptions, errors },
|
||||
],
|
||||
})
|
||||
25
node_modules/eslint-plugin-cypress/tests-legacy/lib/rules/no-async-tests.js
generated
vendored
Normal file
25
node_modules/eslint-plugin-cypress/tests-legacy/lib/rules/no-async-tests.js
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
'use strict'
|
||||
|
||||
const rule = require('../../../lib/rules/no-async-tests')
|
||||
const RuleTester = require('eslint').RuleTester
|
||||
|
||||
const ruleTester = new RuleTester()
|
||||
|
||||
const errors = [{ messageId: 'unexpected' }]
|
||||
// async functions are an ES2017 feature
|
||||
const parserOptions = { ecmaVersion: 8 }
|
||||
|
||||
ruleTester.run('no-async-tests', rule, {
|
||||
valid: [
|
||||
{ code: 'it(\'a test case\', () => { cy.get(\'.someClass\'); })', parserOptions },
|
||||
{ code: 'it(\'a test case\', async () => { await somethingAsync(); })', parserOptions },
|
||||
{ code: 'async function nonTestFn () { return await somethingAsync(); }', parserOptions },
|
||||
{ code: 'const nonTestArrowFn = async () => { await somethingAsync(); }', parserOptions },
|
||||
],
|
||||
invalid: [
|
||||
{ code: 'it(\'a test case\', async () => { cy.get(\'.someClass\'); })', parserOptions, errors },
|
||||
{ code: 'test(\'a test case\', async () => { cy.get(\'.someClass\'); })', parserOptions, errors },
|
||||
{ code: 'it(\'a test case\', async function () { cy.get(\'.someClass\'); })', parserOptions, errors },
|
||||
{ code: 'test(\'a test case\', async function () { cy.get(\'.someClass\'); })', parserOptions, errors },
|
||||
],
|
||||
})
|
||||
49
node_modules/eslint-plugin-cypress/tests-legacy/lib/rules/no-force.js
generated
vendored
Normal file
49
node_modules/eslint-plugin-cypress/tests-legacy/lib/rules/no-force.js
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
'use strict'
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const rule = require('../../../lib/rules/no-force')
|
||||
|
||||
const RuleTester = require('eslint').RuleTester
|
||||
|
||||
const errors = [{ messageId: 'unexpected' }]
|
||||
const parserOptions = { ecmaVersion: 2018 }
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Tests
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
let ruleTester = new RuleTester()
|
||||
|
||||
ruleTester.run('no-force', rule, {
|
||||
|
||||
valid: [
|
||||
{ code: `cy.get('button').click()`, parserOptions },
|
||||
{ code: `cy.get('button').click({multiple: true})`, parserOptions },
|
||||
{ code: `cy.get('button').dblclick()`, parserOptions },
|
||||
{ code: `cy.get('input').type('somth')`, parserOptions },
|
||||
{ code: `cy.get('input').type('somth', {anyoption: true})`, parserOptions },
|
||||
{ code: `cy.get('input').trigger('click', {anyoption: true})`, parserOptions },
|
||||
{ code: `cy.get('input').rightclick({anyoption: true})`, parserOptions },
|
||||
{ code: `cy.get('input').check()`, parserOptions },
|
||||
{ code: `cy.get('input').select()`, parserOptions },
|
||||
{ code: `cy.get('input').focus()`, parserOptions },
|
||||
{ code: `cy.document().trigger("keydown", { ...event })`, parserOptions },
|
||||
],
|
||||
|
||||
invalid: [
|
||||
{ code: `cy.get('button').click({force: true})`, parserOptions, errors },
|
||||
{ code: `cy.get('button').dblclick({force: true})`, parserOptions, errors },
|
||||
{ code: `cy.get('input').type('somth', {force: true})`, parserOptions, errors },
|
||||
{ code: `cy.get('div').find('.foo').type('somth', {force: true})`, parserOptions, errors },
|
||||
{ code: `cy.get('div').find('.foo').find('.bar').click({force: true})`, parserOptions, errors },
|
||||
{ code: `cy.get('div').find('.foo').find('.bar').trigger('change', {force: true})`, parserOptions, errors },
|
||||
{ code: `cy.get('input').trigger('click', {force: true})`, parserOptions, errors },
|
||||
{ code: `cy.get('input').rightclick({force: true})`, parserOptions, errors },
|
||||
{ code: `cy.get('input').check({force: true})`, parserOptions, errors },
|
||||
{ code: `cy.get('input').select({force: true})`, parserOptions, errors },
|
||||
{ code: `cy.get('input').focus({force: true})`, parserOptions, errors },
|
||||
],
|
||||
})
|
||||
37
node_modules/eslint-plugin-cypress/tests-legacy/lib/rules/no-pause.js
generated
vendored
Normal file
37
node_modules/eslint-plugin-cypress/tests-legacy/lib/rules/no-pause.js
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
'use strict'
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const rule = require('../../../lib/rules/no-pause')
|
||||
|
||||
const RuleTester = require('eslint').RuleTester
|
||||
|
||||
const errors = [{ messageId: 'unexpected' }]
|
||||
const parserOptions = { ecmaVersion: 2018 }
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Tests
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const ruleTester = new RuleTester()
|
||||
|
||||
ruleTester.run('no-pause', rule, {
|
||||
|
||||
valid: [
|
||||
{ code: `pause()`, parserOptions },
|
||||
{ code: `cy.get('button').dblclick()`, parserOptions },
|
||||
],
|
||||
|
||||
invalid: [
|
||||
{ code: `cy.pause()`, parserOptions, errors },
|
||||
{ code: `cy.pause({ log: false })`, parserOptions, errors },
|
||||
{ code: `cy.get('button').pause()`, parserOptions, errors },
|
||||
{
|
||||
code: `cy.get('a').should('have.attr', 'href').and('match', /dashboard/).pause()`,
|
||||
parserOptions,
|
||||
errors
|
||||
}
|
||||
],
|
||||
})
|
||||
71
node_modules/eslint-plugin-cypress/tests-legacy/lib/rules/no-unnecessary-waiting.js
generated
vendored
Normal file
71
node_modules/eslint-plugin-cypress/tests-legacy/lib/rules/no-unnecessary-waiting.js
generated
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
'use strict'
|
||||
|
||||
const rule = require('../../../lib/rules/no-unnecessary-waiting')
|
||||
const RuleTester = require('eslint').RuleTester
|
||||
|
||||
const ruleTester = new RuleTester()
|
||||
|
||||
const errors = [{ messageId: 'unexpected' }]
|
||||
const parserOptions = { ecmaVersion: 6, sourceType: 'module' }
|
||||
|
||||
ruleTester.run('no-unnecessary-waiting', rule, {
|
||||
valid: [
|
||||
{ code: 'foo.wait(10)', parserOptions },
|
||||
|
||||
{ code: 'cy.wait("@someRequest")', parserOptions },
|
||||
{ code: 'cy.wait("@someRequest", { log: false })', parserOptions },
|
||||
{ code: 'cy.wait("@someRequest").then((xhr) => xhr)', parserOptions },
|
||||
{ code: 'cy.wait(["@someRequest", "@anotherRequest"])', parserOptions },
|
||||
|
||||
{ code: 'cy.clock(5000)', parserOptions },
|
||||
{ code: 'cy.scrollTo(0, 10)', parserOptions },
|
||||
{ code: 'cy.tick(500)', parserOptions },
|
||||
|
||||
{ code: 'const someRequest="@someRequest"; cy.wait(someRequest)', parserOptions, errors },
|
||||
{ code: 'function customWait (alias = "@someRequest") { cy.wait(alias) }', parserOptions, errors },
|
||||
{ code: 'const customWait = (alias = "@someRequest") => { cy.wait(alias) }', parserOptions, errors },
|
||||
{ code: 'function customWait (ms) { cy.wait(ms) }', parserOptions, errors },
|
||||
{ code: 'const customWait = (ms) => { cy.wait(ms) }', parserOptions, errors },
|
||||
|
||||
{ code: 'import BAR_BAZ from "bar-baz"; cy.wait(BAR_BAZ)', parserOptions },
|
||||
{ code: 'import { FOO_BAR } from "foo-bar"; cy.wait(FOO_BAR)', parserOptions },
|
||||
{ code: 'import * as wildcard from "wildcard"; cy.wait(wildcard.value)', parserOptions },
|
||||
{ code: 'import { NAME as OTHER_NAME } from "rename"; cy.wait(OTHER_NAME)', parserOptions },
|
||||
|
||||
// disable the eslint rule
|
||||
{
|
||||
code: `
|
||||
cy.wait(100); // eslint-disable-line no-unnecessary-waiting
|
||||
`,
|
||||
parserOptions,
|
||||
},
|
||||
{
|
||||
code: `
|
||||
/* eslint-disable-next-line no-unnecessary-waiting */
|
||||
cy.wait(100)
|
||||
`,
|
||||
parserOptions,
|
||||
},
|
||||
{
|
||||
code: `
|
||||
/* eslint-disable no-unnecessary-waiting */
|
||||
cy.wait(100)
|
||||
/* eslint-enable no-unnecessary-waiting */
|
||||
`,
|
||||
parserOptions,
|
||||
},
|
||||
],
|
||||
|
||||
invalid: [
|
||||
{ code: 'cy.wait(0)', parserOptions, errors },
|
||||
{ code: 'cy.wait(100)', parserOptions, errors },
|
||||
{ code: 'cy.wait(5000)', parserOptions, errors },
|
||||
{ code: 'const someNumber=500; cy.wait(someNumber)', parserOptions, errors },
|
||||
{ code: 'function customWait (ms = 1) { cy.wait(ms) }', parserOptions, errors },
|
||||
{ code: 'const customWait = (ms = 1) => { cy.wait(ms) }', parserOptions, errors },
|
||||
|
||||
{ code: 'cy.get(".some-element").wait(10)', parserOptions, errors },
|
||||
{ code: 'cy.get(".some-element").contains("foo").wait(10)', parserOptions, errors },
|
||||
{ code: 'const customWait = (ms = 1) => { cy.get(".some-element").wait(ms) }', parserOptions, errors },
|
||||
],
|
||||
})
|
||||
31
node_modules/eslint-plugin-cypress/tests-legacy/lib/rules/require-data-selectors.js
generated
vendored
Normal file
31
node_modules/eslint-plugin-cypress/tests-legacy/lib/rules/require-data-selectors.js
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
'use strict'
|
||||
|
||||
const rule = require('../../../lib/rules/require-data-selectors')
|
||||
const RuleTester = require('eslint').RuleTester
|
||||
|
||||
const ruleTester = new RuleTester()
|
||||
|
||||
const errors = [{ messageId: 'unexpected' }]
|
||||
const parserOptions = { ecmaVersion: 6 }
|
||||
|
||||
ruleTester.run('require-data-selectors', rule, {
|
||||
valid: [
|
||||
{ code: 'cy.get(\'[data-cy=submit]\').click()', parserOptions },
|
||||
{ code: 'cy.get(\'[data-QA=submit]\')', parserOptions },
|
||||
{ code: 'cy.clock(5000)', parserOptions },
|
||||
{ code: 'cy.scrollTo(0, 10)', parserOptions },
|
||||
{ code: 'cy.tick(500)', parserOptions },
|
||||
{ code: 'cy.get(\`[data-cy=${1}]\`)', parserOptions }, // eslint-disable-line no-useless-escape
|
||||
{ code: 'cy.get("@my-alias")', parserOptions, errors },
|
||||
{ code: 'cy.get(`@my-alias`)', parserOptions, errors },
|
||||
],
|
||||
|
||||
invalid: [
|
||||
{ code: 'cy.get(\'[daedta-cy=submit]\').click()', parserOptions, errors },
|
||||
{ code: 'cy.get(\'[d-cy=submit]\')', parserOptions, errors },
|
||||
{ code: 'cy.get(".btn-large").click()', parserOptions, errors },
|
||||
{ code: 'cy.get(".btn-.large").click()', parserOptions, errors },
|
||||
{ code: 'cy.get(".a")', parserOptions, errors },
|
||||
{ code: 'cy.get(\`[daedta-cy=${1}]\`)', parserOptions, errors }, // eslint-disable-line no-useless-escape
|
||||
],
|
||||
})
|
||||
56
node_modules/eslint-plugin-cypress/tests-legacy/lib/rules/unsafe-to-chain-command.js
generated
vendored
Normal file
56
node_modules/eslint-plugin-cypress/tests-legacy/lib/rules/unsafe-to-chain-command.js
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
'use strict'
|
||||
|
||||
const rule = require('../../../lib/rules/unsafe-to-chain-command')
|
||||
const RuleTester = require('eslint').RuleTester
|
||||
|
||||
const ruleTester = new RuleTester()
|
||||
|
||||
const errors = [{ messageId: 'unexpected' }]
|
||||
const parserOptions = { ecmaVersion: 6 }
|
||||
|
||||
ruleTester.run('action-ends-chain', rule, {
|
||||
valid: [
|
||||
{
|
||||
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");',
|
||||
parserOptions,
|
||||
},
|
||||
{
|
||||
code: 'cy.focused().should("be.visible");',
|
||||
parserOptions,
|
||||
},
|
||||
{
|
||||
code: 'cy.submitBtn().click();',
|
||||
parserOptions,
|
||||
},
|
||||
],
|
||||
|
||||
invalid: [
|
||||
{
|
||||
code: 'cy.get("new-todo").type("todo A{enter}").should("have.class", "active");',
|
||||
parserOptions,
|
||||
errors,
|
||||
},
|
||||
{
|
||||
code: 'cy.get("new-todo").type("todo A{enter}").type("todo B{enter}");',
|
||||
parserOptions,
|
||||
errors,
|
||||
},
|
||||
{
|
||||
code: 'cy.get("new-todo").focus().should("have.class", "active");',
|
||||
parserOptions,
|
||||
errors,
|
||||
},
|
||||
{
|
||||
code: 'cy.get("new-todo").customType("todo A{enter}").customClick();',
|
||||
options: [{ methods: ['customType', 'customClick'] }],
|
||||
parserOptions,
|
||||
errors,
|
||||
},
|
||||
{
|
||||
code: 'cy.get("new-todo").customPress("Enter").customScroll();',
|
||||
options: [{ methods: [/customPress/, /customScroll/] }],
|
||||
parserOptions,
|
||||
errors,
|
||||
},
|
||||
],
|
||||
})
|
||||
26
node_modules/eslint-plugin-cypress/tests/config.js
generated
vendored
Normal file
26
node_modules/eslint-plugin-cypress/tests/config.js
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
/* global describe, it, expect */
|
||||
'use strict'
|
||||
|
||||
const globals = require('globals')
|
||||
const config = require('../lib/flat.js')
|
||||
|
||||
describe('globals languageOptions', () => {
|
||||
const languageOptions = config.configs.globals.languageOptions
|
||||
|
||||
it('should not mutate globals', () => {
|
||||
expect(globals.browser).not.toHaveProperty('cy')
|
||||
expect(globals.mocha).not.toHaveProperty('cy')
|
||||
})
|
||||
|
||||
it('should include other globals', () => {
|
||||
expect(languageOptions.globals).toEqual(expect.objectContaining(globals.browser))
|
||||
expect(languageOptions.globals).toEqual(expect.objectContaining(globals.mocha))
|
||||
})
|
||||
|
||||
it('should include cypress globals', () => {
|
||||
expect(languageOptions.globals).toEqual(expect.objectContaining({
|
||||
cy: false,
|
||||
Cypress: false,
|
||||
}))
|
||||
})
|
||||
})
|
||||
34
node_modules/eslint-plugin-cypress/tests/lib/rules/assertion-before-screenshot.js
generated
vendored
Normal file
34
node_modules/eslint-plugin-cypress/tests/lib/rules/assertion-before-screenshot.js
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
'use strict'
|
||||
|
||||
const rule = require('../../../lib/rules/assertion-before-screenshot')
|
||||
const RuleTester = require('eslint').RuleTester
|
||||
|
||||
const ruleTester = new RuleTester()
|
||||
|
||||
const errors = [{ messageId: 'unexpected' }]
|
||||
|
||||
ruleTester.run('assertion-before-screenshot', rule, {
|
||||
valid: [
|
||||
{ code: 'cy.get(".some-element"); cy.screenshot();' },
|
||||
{ code: 'cy.get(".some-element").should("exist").screenshot();' },
|
||||
{ code: 'cy.get(".some-element").should("exist").screenshot().click()' },
|
||||
{ code: 'cy.get(".some-element").should("exist"); if(true) cy.screenshot();' },
|
||||
{ code: 'if(true) { cy.get(".some-element").should("exist"); cy.screenshot(); }' },
|
||||
{ code: 'cy.get(".some-element").should("exist"); if(true) { cy.screenshot(); }' },
|
||||
{ code: 'const a = () => { cy.get(".some-element").should("exist"); cy.screenshot(); }' },
|
||||
{ code: 'cy.get(".some-element").should("exist").and("be.visible"); cy.screenshot();' },
|
||||
{ code: 'cy.get(".some-element").contains("Text"); cy.screenshot();' },
|
||||
],
|
||||
|
||||
invalid: [
|
||||
{ code: 'cy.screenshot()', errors },
|
||||
{ code: 'cy.visit("somepage"); cy.screenshot();', errors },
|
||||
{ code: 'cy.custom(); cy.screenshot()', errors },
|
||||
{ code: 'cy.get(".some-element").click(); cy.screenshot()', errors },
|
||||
{ code: 'cy.get(".some-element").click().screenshot()', errors },
|
||||
{ code: 'if(true) { cy.get(".some-element").click(); cy.screenshot(); }', errors },
|
||||
{ code: 'cy.get(".some-element").click(); if(true) { cy.screenshot(); }', errors },
|
||||
{ code: 'cy.get(".some-element"); function a() { cy.screenshot(); }', errors },
|
||||
{ code: 'cy.get(".some-element"); const a = () => { cy.screenshot(); }', errors },
|
||||
],
|
||||
})
|
||||
37
node_modules/eslint-plugin-cypress/tests/lib/rules/no-assigning-return-values.js
generated
vendored
Normal file
37
node_modules/eslint-plugin-cypress/tests/lib/rules/no-assigning-return-values.js
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
'use strict'
|
||||
|
||||
const rule = require('../../../lib/rules/no-assigning-return-values')
|
||||
const RuleTester = require('eslint').RuleTester
|
||||
|
||||
const ruleTester = new RuleTester()
|
||||
|
||||
const errors = [{ messageId: 'unexpected' }]
|
||||
|
||||
ruleTester.run('no-assigning-return-values', rule, {
|
||||
valid: [
|
||||
{ code: 'var foo = true;' },
|
||||
{ code: 'let foo = true;' },
|
||||
{ code: 'const foo = true;' },
|
||||
{ code: 'const foo = bar();' },
|
||||
{ code: 'const foo = bar().baz();' },
|
||||
{ code: 'const spy = cy.spy();' },
|
||||
{ code: 'const spy = cy.spy().as();' },
|
||||
{ code: 'const stub = cy.stub();' },
|
||||
{ code: 'const result = cy.now();' },
|
||||
{ code: 'const state = cy.state();' },
|
||||
{ code: 'cy.get("foo");' },
|
||||
{ code: 'cy.contains("foo").click();' },
|
||||
],
|
||||
|
||||
invalid: [
|
||||
{ code: 'let a = cy.get("foo")', errors },
|
||||
{ code: 'const a = cy.get("foo")', errors },
|
||||
{ code: 'var a = cy.get("foo")', errors },
|
||||
|
||||
{ code: 'let a = cy.contains("foo")', errors },
|
||||
{ code: 'let a = cy.window()', errors },
|
||||
{ code: 'let a = cy.wait("@something")', errors },
|
||||
|
||||
{ code: 'let a = cy.contains("foo").click()', errors },
|
||||
],
|
||||
})
|
||||
23
node_modules/eslint-plugin-cypress/tests/lib/rules/no-async-before.js
generated
vendored
Normal file
23
node_modules/eslint-plugin-cypress/tests/lib/rules/no-async-before.js
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
'use strict'
|
||||
|
||||
const rule = require('../../../lib/rules/no-async-before')
|
||||
const RuleTester = require('eslint').RuleTester
|
||||
|
||||
const ruleTester = new RuleTester()
|
||||
|
||||
const errors = [{ messageId: 'unexpected' }]
|
||||
|
||||
ruleTester.run('no-async-before', rule, {
|
||||
valid: [
|
||||
{ code: 'before(\'a before case\', () => { cy.get(\'.someClass\'); })' },
|
||||
{ code: 'before(\'a before case\', async () => { await somethingAsync(); })' },
|
||||
{ code: 'async function nonTestFn () { return await somethingAsync(); }' },
|
||||
{ code: 'const nonTestArrowFn = async () => { await somethingAsync(); }' },
|
||||
],
|
||||
invalid: [
|
||||
{ code: 'before(\'a test case\', async () => { cy.get(\'.someClass\'); })', errors },
|
||||
{ code: 'beforeEach(\'a test case\', async () => { cy.get(\'.someClass\'); })', errors },
|
||||
{ code: 'before(\'a test case\', async function () { cy.get(\'.someClass\'); })', errors },
|
||||
{ code: 'beforeEach(\'a test case\', async function () { cy.get(\'.someClass\'); })', errors },
|
||||
],
|
||||
})
|
||||
23
node_modules/eslint-plugin-cypress/tests/lib/rules/no-async-tests.js
generated
vendored
Normal file
23
node_modules/eslint-plugin-cypress/tests/lib/rules/no-async-tests.js
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
'use strict'
|
||||
|
||||
const rule = require('../../../lib/rules/no-async-tests')
|
||||
const RuleTester = require('eslint').RuleTester
|
||||
|
||||
const ruleTester = new RuleTester()
|
||||
|
||||
const errors = [{ messageId: 'unexpected' }]
|
||||
|
||||
ruleTester.run('no-async-tests', rule, {
|
||||
valid: [
|
||||
{ code: 'it(\'a test case\', () => { cy.get(\'.someClass\'); })' },
|
||||
{ code: 'it(\'a test case\', async () => { await somethingAsync(); })' },
|
||||
{ code: 'async function nonTestFn () { return await somethingAsync(); }' },
|
||||
{ code: 'const nonTestArrowFn = async () => { await somethingAsync(); }' },
|
||||
],
|
||||
invalid: [
|
||||
{ code: 'it(\'a test case\', async () => { cy.get(\'.someClass\'); })', errors },
|
||||
{ code: 'test(\'a test case\', async () => { cy.get(\'.someClass\'); })', errors },
|
||||
{ code: 'it(\'a test case\', async function () { cy.get(\'.someClass\'); })', errors },
|
||||
{ code: 'test(\'a test case\', async function () { cy.get(\'.someClass\'); })', errors },
|
||||
],
|
||||
})
|
||||
23
node_modules/eslint-plugin-cypress/tests/lib/rules/no-debug.js
generated
vendored
Normal file
23
node_modules/eslint-plugin-cypress/tests/lib/rules/no-debug.js
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
'use strict'
|
||||
|
||||
const rule = require('../../../lib/rules/no-debug')
|
||||
const RuleTester = require('eslint').RuleTester
|
||||
|
||||
const ruleTester = new RuleTester()
|
||||
|
||||
const errors = [{ messageId: 'unexpected' }]
|
||||
|
||||
ruleTester.run('no-debug', rule, {
|
||||
|
||||
valid: [
|
||||
{ code: `debug()` },
|
||||
{ code: `cy.get('button').dblclick()` },
|
||||
],
|
||||
|
||||
invalid: [
|
||||
{ code: `cy.debug()`, errors },
|
||||
{ code: `cy.debug({ log: false })`, errors },
|
||||
{ code: `cy.get('button').debug()`, errors },
|
||||
{ code: `cy.get('a').should('have.attr', 'href').and('match', /dashboard/).debug()`, errors }
|
||||
],
|
||||
})
|
||||
39
node_modules/eslint-plugin-cypress/tests/lib/rules/no-force.js
generated
vendored
Normal file
39
node_modules/eslint-plugin-cypress/tests/lib/rules/no-force.js
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
'use strict'
|
||||
|
||||
const rule = require('../../../lib/rules/no-force')
|
||||
const RuleTester = require('eslint').RuleTester
|
||||
|
||||
const ruleTester = new RuleTester()
|
||||
|
||||
const errors = [{ messageId: 'unexpected' }]
|
||||
|
||||
ruleTester.run('no-force', rule, {
|
||||
|
||||
valid: [
|
||||
{ code: `cy.get('button').click()` },
|
||||
{ code: `cy.get('button').click({multiple: true})` },
|
||||
{ code: `cy.get('button').dblclick()` },
|
||||
{ code: `cy.get('input').type('somth')` },
|
||||
{ code: `cy.get('input').type('somth', {anyoption: true})` },
|
||||
{ code: `cy.get('input').trigger('click', {anyoption: true})` },
|
||||
{ code: `cy.get('input').rightclick({anyoption: true})` },
|
||||
{ code: `cy.get('input').check()` },
|
||||
{ code: `cy.get('input').select()` },
|
||||
{ code: `cy.get('input').focus()` },
|
||||
{ code: `cy.document().trigger("keydown", { ...event })` },
|
||||
],
|
||||
|
||||
invalid: [
|
||||
{ code: `cy.get('button').click({force: true})`, errors },
|
||||
{ code: `cy.get('button').dblclick({force: true})`, errors },
|
||||
{ code: `cy.get('input').type('somth', {force: true})`, errors },
|
||||
{ code: `cy.get('div').find('.foo').type('somth', {force: true})`, errors },
|
||||
{ code: `cy.get('div').find('.foo').find('.bar').click({force: true})`, errors },
|
||||
{ code: `cy.get('div').find('.foo').find('.bar').trigger('change', {force: true})`, errors },
|
||||
{ code: `cy.get('input').trigger('click', {force: true})`, errors },
|
||||
{ code: `cy.get('input').rightclick({force: true})`, errors },
|
||||
{ code: `cy.get('input').check({force: true})`, errors },
|
||||
{ code: `cy.get('input').select({force: true})`, errors },
|
||||
{ code: `cy.get('input').focus({force: true})`, errors },
|
||||
],
|
||||
})
|
||||
23
node_modules/eslint-plugin-cypress/tests/lib/rules/no-pause.js
generated
vendored
Normal file
23
node_modules/eslint-plugin-cypress/tests/lib/rules/no-pause.js
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
'use strict'
|
||||
|
||||
const rule = require('../../../lib/rules/no-pause')
|
||||
const RuleTester = require('eslint').RuleTester
|
||||
|
||||
const ruleTester = new RuleTester()
|
||||
|
||||
const errors = [{ messageId: 'unexpected' }]
|
||||
|
||||
ruleTester.run('no-pause', rule, {
|
||||
|
||||
valid: [
|
||||
{ code: `pause()` },
|
||||
{ code: `cy.get('button').dblclick()` },
|
||||
],
|
||||
|
||||
invalid: [
|
||||
{ code: `cy.pause()`, errors },
|
||||
{ code: `cy.pause({ log: false })`, errors },
|
||||
{ code: `cy.get('button').pause()`, errors },
|
||||
{ code: `cy.get('a').should('have.attr', 'href').and('match', /dashboard/).pause()`, errors }
|
||||
],
|
||||
})
|
||||
47
node_modules/eslint-plugin-cypress/tests/lib/rules/no-unnecessary-waiting.js
generated
vendored
Normal file
47
node_modules/eslint-plugin-cypress/tests/lib/rules/no-unnecessary-waiting.js
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
'use strict'
|
||||
|
||||
const rule = require('../../../lib/rules/no-unnecessary-waiting')
|
||||
const RuleTester = require('eslint').RuleTester
|
||||
|
||||
const ruleTester = new RuleTester()
|
||||
|
||||
const errors = [{ messageId: 'unexpected' }]
|
||||
|
||||
ruleTester.run('no-unnecessary-waiting', rule, {
|
||||
valid: [
|
||||
{ code: 'foo.wait(10)' },
|
||||
|
||||
{ code: 'cy.wait("@someRequest")' },
|
||||
{ code: 'cy.wait("@someRequest", { log: false })' },
|
||||
{ code: 'cy.wait("@someRequest").then((xhr) => xhr)' },
|
||||
{ code: 'cy.wait(["@someRequest", "@anotherRequest"])' },
|
||||
|
||||
{ code: 'cy.clock(5000)' },
|
||||
{ code: 'cy.scrollTo(0, 10)' },
|
||||
{ code: 'cy.tick(500)' },
|
||||
|
||||
{ code: 'const someRequest="@someRequest"; cy.wait(someRequest)' },
|
||||
{ code: 'function customWait (alias = "@someRequest") { cy.wait(alias) }' },
|
||||
{ code: 'const customWait = (alias = "@someRequest") => { cy.wait(alias) }' },
|
||||
{ code: 'function customWait (ms) { cy.wait(ms) }' },
|
||||
{ code: 'const customWait = (ms) => { cy.wait(ms) }' },
|
||||
|
||||
{ code: 'import BAR_BAZ from "bar-baz"; cy.wait(BAR_BAZ)' },
|
||||
{ code: 'import { FOO_BAR } from "foo-bar"; cy.wait(FOO_BAR)' },
|
||||
{ code: 'import * as wildcard from "wildcard"; cy.wait(wildcard.value)' },
|
||||
{ code: 'import { NAME as OTHER_NAME } from "rename"; cy.wait(OTHER_NAME)' },
|
||||
],
|
||||
|
||||
invalid: [
|
||||
{ code: 'cy.wait(0)', errors },
|
||||
{ code: 'cy.wait(100)', errors },
|
||||
{ code: 'cy.wait(5000)', errors },
|
||||
{ code: 'const someNumber=500; cy.wait(someNumber)', errors },
|
||||
{ code: 'function customWait (ms = 1) { cy.wait(ms) }', errors },
|
||||
{ code: 'const customWait = (ms = 1) => { cy.wait(ms) }', errors },
|
||||
|
||||
{ code: 'cy.get(".some-element").wait(10)', errors },
|
||||
{ code: 'cy.get(".some-element").contains("foo").wait(10)', errors },
|
||||
{ code: 'const customWait = (ms = 1) => { cy.get(".some-element").wait(ms) }', errors },
|
||||
],
|
||||
})
|
||||
30
node_modules/eslint-plugin-cypress/tests/lib/rules/require-data-selectors.js
generated
vendored
Normal file
30
node_modules/eslint-plugin-cypress/tests/lib/rules/require-data-selectors.js
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
'use strict'
|
||||
|
||||
const rule = require('../../../lib/rules/require-data-selectors')
|
||||
const RuleTester = require('eslint').RuleTester
|
||||
|
||||
const ruleTester = new RuleTester()
|
||||
|
||||
const errors = [{ messageId: 'unexpected' }]
|
||||
|
||||
ruleTester.run('require-data-selectors', rule, {
|
||||
valid: [
|
||||
{ code: 'cy.get(\'[data-cy=submit]\').click()' },
|
||||
{ code: 'cy.get(\'[data-QA=submit]\')' },
|
||||
{ code: 'cy.clock(5000)' },
|
||||
{ code: 'cy.scrollTo(0, 10)' },
|
||||
{ code: 'cy.tick(500)' },
|
||||
{ code: 'cy.get(\`[data-cy=${1}]\`)' }, // eslint-disable-line no-useless-escape
|
||||
{ code: 'cy.get("@my-alias")' },
|
||||
{ code: 'cy.get(`@my-alias`)' },
|
||||
],
|
||||
|
||||
invalid: [
|
||||
{ code: 'cy.get(\'[daedta-cy=submit]\').click()', errors },
|
||||
{ code: 'cy.get(\'[d-cy=submit]\')', errors },
|
||||
{ code: 'cy.get(".btn-large").click()', errors },
|
||||
{ code: 'cy.get(".btn-.large").click()', errors },
|
||||
{ code: 'cy.get(".a")', errors },
|
||||
{ code: 'cy.get(\`[daedta-cy=${1}]\`)', errors }, // eslint-disable-line no-useless-escape
|
||||
],
|
||||
})
|
||||
34
node_modules/eslint-plugin-cypress/tests/lib/rules/unsafe-to-chain-command.js
generated
vendored
Normal file
34
node_modules/eslint-plugin-cypress/tests/lib/rules/unsafe-to-chain-command.js
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
'use strict'
|
||||
|
||||
const rule = require('../../../lib/rules/unsafe-to-chain-command')
|
||||
const RuleTester = require('eslint').RuleTester
|
||||
|
||||
const ruleTester = new RuleTester()
|
||||
|
||||
const errors = [{ messageId: 'unexpected' }]
|
||||
|
||||
ruleTester.run('action-ends-chain', rule, {
|
||||
valid: [
|
||||
{
|
||||
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");'
|
||||
},
|
||||
{ code: 'cy.focused().should("be.visible");' },
|
||||
{ code: 'cy.submitBtn().click();' },
|
||||
],
|
||||
|
||||
invalid: [
|
||||
{ code: 'cy.get("new-todo").type("todo A{enter}").should("have.class", "active");', errors },
|
||||
{ code: 'cy.get("new-todo").type("todo A{enter}").type("todo B{enter}");', errors },
|
||||
{ code: 'cy.get("new-todo").focus().should("have.class", "active");', errors },
|
||||
{
|
||||
code: 'cy.get("new-todo").customType("todo A{enter}").customClick();',
|
||||
options: [{ methods: ['customType', 'customClick'] }],
|
||||
errors,
|
||||
},
|
||||
{
|
||||
code: 'cy.get("new-todo").customPress("Enter").customScroll();',
|
||||
options: [{ methods: ['customPress', 'customScroll'] }],
|
||||
errors,
|
||||
},
|
||||
],
|
||||
})
|
||||
Reference in New Issue
Block a user