GithubHelp home page GithubHelp logo

eslint-plugin-cypress's Introduction

Cypress ESLint Plugin CircleCI

An ESLint plugin for your Cypress tests.

Note: If you installed ESLint globally then you must also install eslint-plugin-cypress globally.

Installation

Prerequisites: ESLint v7 or v8. ESLint v9 is not supported yet.

npm install eslint-plugin-cypress --save-dev

or

yarn add eslint-plugin-cypress --dev

Usage

Add an .eslintrc.json file to your cypress directory with the following:

{
  "plugins": [
    "cypress"
  ]
}

You can add rules:

{
  "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"
  }
}

You can allow certain globals provided by Cypress:

{
  "env": {
    "cypress/globals": true
  }
}

Recommended configuration

Use the recommended configuration and you can forego configuring plugins, rules, and env individually. See below for which rules are included.

{
  "extends": [
    "plugin:cypress/recommended"
  ]
}

Disable rules

You can disable specific rules per file, for a portion of a file, or for a single line.

Disable the cypress/no-unnecessary-waiting rule for the entire file by placing this at the start of the file:

/* eslint-disable cypress/no-unnecessary-waiting */

Disable the cypress/no-unnecessary-waiting rule for only a portion of the file:

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:

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:

it('waits for a second', () => {
  ...
  // eslint-disable-next-line cypress/no-unnecessary-waiting
  cy.wait(1000)
  ...
})

For more, see the ESLint rules documentation.

Rules

These rules enforce some of the best practices recommended for using Cypress.

Rules with a check mark (✅) are enabled by default while using the plugin:cypress/recommended config.

Rule ID Description
no-assigning-return-values Prevent assigning return values of cy calls
no-unnecessary-waiting Prevent waiting for arbitrary time periods
no-async-tests Prevent using async/await in Cypress test case
unsafe-to-chain-command Prevent chaining from unsafe to chain commands
no-force Disallow using force: true with action commands
assertion-before-screenshot Ensure screenshots are preceded by an assertion
require-data-selectors Only allow data-* attribute selectors (require-data-selectors)
no-pause Disallow cy.pause() parent command

Mocha and Chai

Cypress is built on top of Mocha and Chai. See the following sections for information on using ESLint plugins eslint-plugin-mocha and eslint-plugin-chai-friendly together with eslint-plugin-cypress.

Mocha .only and .skip

During test spec development, Mocha exclusive tests .only or Mocha inclusive tests .skip may be used to control which tests are executed, as described in the Cypress documentation Excluding and Including Tests. To apply corresponding rules, you can install and use eslint-plugin-mocha. The rule mocha/no-exclusive-tests detects the use of .only and the mocha/no-skipped-tests rule detects the use of .skip:

npm install --save-dev eslint-plugin-mocha

In your .eslintrc.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:

{
  "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.

npm install --save-dev eslint-plugin-chai-friendly

In your .eslintrc.json:

{
  "plugins": [
    "cypress",
    "chai-friendly"
  ],
  "rules": {
    "no-unused-expressions": 0,
    "chai-friendly/no-unused-expressions": 2
  }
}

Or you can simply add its recommended config:

{
  "extends": ["plugin:chai-friendly/recommended"]
}

Contributing

Please see our Contributing Guideline which explains how to contribute rules or other fixes and features to the repo.

eslint-plugin-cypress's People

Contributors

arcturus5404 avatar arvigeus avatar atofstryker avatar bahmutov avatar bluewinds avatar brettz9 avatar bz2 avatar cacieprins avatar chrisbreiding avatar dominicfraser avatar erik-outreach avatar ertrzyiks avatar hyzual avatar jennifer-shehane avatar jordanpowell88 avatar kuzzaka avatar lukeapage avatar maddhruv avatar mastrzyz avatar meeroslav avatar mikemcc399 avatar mroca avatar mschile avatar passbyval avatar pawel-schmidt avatar randing89 avatar saladfork avatar sandeepbaldawa avatar strajk avatar walaszczykm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

eslint-plugin-cypress's Issues

Importing plugin mutates globals.browser

Currently, importing the 'cypress' plugin changes the meaning of the 'browser' global variables as defined by eslint.

This has two effects:

  • The cypress globals may be accepted for files where that is not intended.
  • Running eslint directly and through for instance vscode can get different results.

Issue is due to misuse of Object.assign() in index.js.

"Cypress chaining syntax" not supported (?)

Is it possible that the "Cypress chaining syntax" is not supported by this plugin?

This does NOT result in a eslint error

    cy.visit('http://localhost/8080')
        .wait(5000)     // <--- this is unnecessary

this DOES results in a eslint error

    cy.visit('http://localhost/8080')
    cy.wait(5000)     // <--- this is unnecessary

Thanks!

The automated release is failing 🚨

🚨 The automated release from the master branch failed. 🚨

I recommend you give this issue a high priority, so other packages depending on you could benefit from your bug fixes and new features.

You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. I’m sure you can resolve this 💪.

Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.

Once all the errors are resolved, semantic-release will release your package the next time you push a commit to the master branch. You can also manually restart the failed CI job that runs semantic-release.

If you are not sure how to resolve this, here is some links that can help you:

If those don’t help, or if this issue is reporting something you think isn’t right, you can always ask the humans behind semantic-release.


Invalid npm token.

The npm token configured in the NPM_TOKEN environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/.

If you are using Two-Factor Authentication, make configure the auth-only level is supported. semantic-release cannot publish with the default auth-and-writes level.

Please make sure to set the NPM_TOKEN environment variable in your CI with the exact value of the npm token.


Good luck with your project ✨

Your semantic-release bot 📦🚀

Suggestion: Add rule(s) to disallow debugging-related Cypress calls

#57 already covers .only, but I think it would be valuable to either have a single rule, or individual rules, to cover other Cypress calls that are usually just for debugging and we don't want to accidentally commit to source control, including:

  • cy.pause
  • xdescribe/xit/.skip
  • .only (Again, see #57)
  • cy.debug

no-unnecessary-waiting: TypeError: Cannot read property 'value' of undefined

using: [email protected]

I have a wrapper for cy.wait
Since 2.8.0 it results in an Cannot read property 'value' of undefined error

const waitForImportToComplete = (timeout = 5000): void => {
    // eslint-disable-next-line cypress/no-unnecessary-waiting
    cy.wait(timeout);
};

The code above will produce the following error message

TypeError: Cannot read property 'value' of undefined
Occurred while linting /home/tomtomsen/development/myproject/src/index.ts:10
    at isIdentifierNumberConstArgument (/home/tomtomsen/development/myproject/node_modules/eslint-plugin-cypress/lib/rules/no-unnecessary-waiting.js:61:64)
    at CallExpression (/home/tomtomsen/development/myproject/node_modules/eslint-plugin-cypress/lib/rules/no-unnecessary-waiting.js:29:41)
    at listeners.(anonymous function).forEach.listener (/home/tomtomsen/development/myproject/node_modules/eslint/lib/linter/safe-emitter.js:45:58)
    at Array.forEach (<anonymous>)
    at Object.emit (/home/tomtomsen/development/myproject/node_modules/eslint/lib/linter/safe-emitter.js:45:38)
    at NodeEventGenerator.applySelector (/home/tomtomsen/development/myproject/node_modules/eslint/lib/linter/node-event-generator.js:254:26)
    at NodeEventGenerator.applySelectors (/home/tomtomsen/development/myproject/node_modules/eslint/lib/linter/node-event-generator.js:283:22)
    at NodeEventGenerator.enterNode (/home/tomtomsen/development/myproject/node_modules/eslint/lib/linter/node-event-generator.js:297:14)
    at CodePathAnalyzer.enterNode (/home/tomtomsen/development/myproject/node_modules/eslint/lib/linter/code-path-analysis/code-path-analyzer.js:634:23)
    at nodeQueue.forEach.traversalInfo (/home/tomtomsen/development/myproject/node_modules/eslint/lib/linter/linter.js:936:32)

const IdentifierValue = resolvedIdentifier.defs[0].node.init.value

It seems that resolvedIdentifier.defs[0] is expected to be from type Variable but got ParameterDefinition, which does not have a node.init.value property.
I was not able to find a way to retrieve the default value of a parameter, otherwise i would have proposed a pull request.

scope.resolve is not a function when running eslint

When I run eslint from the command line I get the following error:

scope.resolve is not a function
at isIdentifierNumberConstArgument (/home/ali/dev/planty/node_modules/eslint-plugin-cypress/lib/rules/no-unnecessary-waiting.js:59:36)
...

Looks like it's coming from the no-unnecessary-waiting.js rule. Is this plugin not compatible with eslint 7.8.1 currently?

Lib versions

  • eslint: 7.8.1
  • eslint-plugin-cypress: 2.11.1

no-unnecessary-waiting: Cannot read property 'undefined' of undefined

Hello, I'm testing stability of well known community ESlint plugins with eslint-remote-tester. This ESLint plugin seems to contain a rule which causes linter to crash. ESlint rules should not crash in any condition since this makes all valid linting problems disappear. If this is a false flag please let me know.

CI run: https://github.com/AriPerkkio/eslint-remote-tester/actions/runs/404195602

Crashing rule:

no-unnecessary-waiting

Minimal repro:

cy.wait(1000); // OK

const LOCAL_WAIT_TIME = 1000;
cy.wait(LOCAL_WAIT_TIME); // OK

import { EXTERNAL_WAIT_TIME } from './constants';
cy.wait(EXTERNAL_WAIT_TIME); // Cannot read property 'undefined' of undefined
"eslint-plugin-cypress": "^2.11.2"
  "plugins": ["cypress"],
  "extends": ["plugin:cypress/recommended"],
  "rules": {
    "cypress/no-force": "error",
    "cypress/assertion-before-screenshot": "error",
    "cypress/require-data-selectors": "error"
  }
Errors from real-world examples

Rule: no-unnecessary-waiting

Message: Cannot read property 'undefined' of undefined
Path: determined-ai/determined/webui/cypress/cypress/integration/02-tasks.spec.ts
Link

      cy.get('button[aria-label="Notebook"]').should('be.visible').click();
      cy.get(`${recordSelector}:first .ant-dropdown-trigger`).click();
      cy.get(overflowSelector).contains(/kill/i).click();
      // Using the server/route approach to detect endpoint calls does not work
with new API
      cy.wait(DEFAULT_WAIT_TIME);
      cy.visit('/det/tasks');
      cy.get(recordSelector).contains(/terminated/i).should('be.visible');
    });
  });
Error:
TypeError: Cannot read property 'undefined' of undefined
Occurred while linting <text>:31
    at isIdentifierNumberConstArgument (/home/runner/work/eslint-remote-tester/eslint-remote-tester/ci/node_modules/eslint-plugin-cypress/lib/rules/no-unnecessary-waiting.js:72:39)
    at CallExpression (/home/runner/work/eslint-remote-tester/eslint-remote-tester/ci/node_modules/eslint-plugin-cypress/lib/rules/no-unnecessary-waiting.js:22:15)
    at /home/runner/work/eslint-remote-tester/eslint-remote-tester/node_modules/eslint/lib/linter/safe-emitter.js:45:58
    at Array.forEach (<anonymous>)
    at Object.emit (/home/runner/work/eslint-remote-tester/eslint-remote-tester/node_modules/eslint/lib/linter/safe-emitter.js:45:38)
    at NodeEventGenerator.applySelector (/home/runner/work/eslint-remote-tester/eslint-remote-tester/node_modules/eslint/lib/linter/node-event-generator.js:254:26)
    at NodeEventGenerator.applySelectors (/home/runner/work/eslint-remote-tester/eslint-remote-tester/node_modules/eslint/lib/linter/node-event-generator.js:283:22)
    at NodeEventGenerator.enterNode (/home/runner/work/eslint-remote-tester/eslint-remote-tester/node_modules/eslint/lib/linter/node-event-generator.js:297:14)
    at CodePathAnalyzer.enterNode (/home/runner/work/eslint-remote-tester/eslint-remote-tester/node_modules/eslint/lib/linter/code-path-analysis/code-path-analyzer.js:711:23)
    at /home/runner/work/eslint-remote-tester/eslint-remote-tester/node_modules/eslint/lib/linter/linter.js:952:32

Need a yarn installation support

I used yarn add eslint-plugin-cypress --save-dev
But things are not working as every time I run this script It shows waiting or error.

Need an update for yarn support.

cypress/no-async-tests and cy.stub()

I receive a "cypress/no-async-tests" when using cy.stub() in an asynchronous method. Is this intended? Stub shouldn't affect asynchronous behavior.

Add opinionated rules

Would be cool if this plugin could do things like warn on calls to .wait(), and enforce other Cypress best practices.

Using exported constant in `cy.wait()` throws "TypeError: Cannot read property 'undefined' of undefined"

Steps to reproduce

  • In a typescript file, define a const number
  • In a second typescript file, import that const
  • Use the imported const in a cy.wait() call

Expected behavior

  • See "no-unnecessary-waiting" ESLint violation

Actual behavior

  • See "TypeError: Cannot read property 'undefined' of undefined", which can't be ignored by ESLint

Stacktrace:

TypeError: Cannot read property 'undefined' of undefined
Occurred while linting filename.ts:15
at isIdentifierNumberConstArgument (/node_modules/eslint-plugin-cypress/lib/rules/no-unnecessary-waiting.js:72:39)
at CallExpression (/node_modules/eslint-plugin-cypress/lib/rules/no-unnecessary-waiting.js:22:15)
at /node_modules/eslint/lib/linter/safe-emitter.js:45:58

Relevant line

const param = definition.node.params[definition.index]

How to override rules?

I can't override the rules for this plugin, I want to use double brackets instead of one, I used this:

"rules": {
        "cypress/cypress": ["error", { "singleQuote": true }]
}

Any suggestions?

require-data-selectors rule should not apply to cy.get('@alias')

Hello,

I was in the midst of updating Cypress related packages, and updated this package to the latest 2.9.0 release. I also realized there's the require-data-selectors rule which I recently enabled as a warning. However, now I have a whole bunch of warnings for places where I use aliases, e.g.

cy.get('[data-test=a]').as('a'); // this is fine
cy.get('@a'); // this is a warning

Minor issue as this is a non-essential rule to us, but I thought for posterity it is worth mentioning.

Handle 'no-unused-expressions' violations due to use of Chai expect

Using a Chai expect expression in a test with the StandardJS ESLint config will throw the ESLint error:

error  Expected an assignment or function call and instead saw an expression  no-unused-expressions

Since Chai is bundled with Cypress I think it only makes sense that eslint-plugin-cypress handle this without the user having to install a separate plugin to handle Chai expressions.

no-force: Cannot read property 'name' of undefined

Hello, I'm testing stability of well known community ESlint plugins with eslint-remote-tester. This ESLint plugin seems to contain a rule which causes linter to crash. ESlint rules should not crash in any condition since this makes all valid linting problems disappear. If this is a false flag please let me know.

CI run: https://github.com/AriPerkkio/eslint-remote-tester/actions/runs/404195602

Crashing rule:

no-force

Minimal repro:

const FORCE_OPTION = { force: true };
cy.get(element).click('A', { ...FORCE_OPTION })
"eslint-plugin-cypress": "^2.11.2"
  "plugins": ["cypress"],
  "extends": ["plugin:cypress/recommended"],
  "rules": {
    "cypress/no-force": "error",
    "cypress/assertion-before-screenshot": "error",
    "cypress/require-data-selectors": "error"
  }
Errors from real-world examples

Rule: no-force

Message: Cannot read property 'name' of undefined
Path: department-of-veterans-affairs/vets-website/src/platform/testing/e2e/cypress/support/form-tester/index.js
Link

    case 'tel':
    case 'email':
    case 'number':
    case 'text': {
      cy.wrap(field.element)
        .clear(FORCE_OPTION)
        .type(field.data, { ...FORCE_OPTION, ...NO_DELAY_OPTION })
        .then(element => {
          // Get the autocomplete menu out of the way.
          if (element.attr('role') === 'combobox') element.blur();
Error:
TypeError: Cannot read property 'name' of undefined
Occurred while linting <text>:304
    at /home/runner/work/eslint-remote-tester/eslint-remote-tester/ci/node_modules/eslint-plugin-cypress/lib/rules/no-force.js:45:98
    at Array.some (<anonymous>)
    at /home/runner/work/eslint-remote-tester/eslint-remote-tester/ci/node_modules/eslint-plugin-cypress/lib/rules/no-force.js:45:66
    at Array.some (<anonymous>)
    at hasOptionForce (/home/runner/work/eslint-remote-tester/eslint-remote-tester/ci/node_modules/eslint-plugin-cypress/lib/rules/no-force.js:44:22)
    at deepCheck (/home/runner/work/eslint-remote-tester/eslint-remote-tester/ci/node_modules/eslint-plugin-cypress/lib/rules/no-force.js:54:13)
    at CallExpression (/home/runner/work/eslint-remote-tester/eslint-remote-tester/ci/node_modules/eslint-plugin-cypress/lib/rules/no-force.js:71:77)
    at /home/runner/work/eslint-remote-tester/eslint-remote-tester/node_modules/eslint/lib/linter/safe-emitter.js:45:58
    at Array.forEach (<anonymous>)
    at Object.emit (/home/runner/work/eslint-remote-tester/eslint-remote-tester/node_modules/eslint/lib/linter/safe-emitter.js:45:38)

Support ESLint 8.x

ESLint v8.0.0 is released 🎉

It would be awesome to have official ESLint 8 support. 👊
I'm happy to help where I can of course 🙂

Documentation for 'no-async-tests' is misleading

The documentation for 'no async tests', while I agree the rule itself is extremely important to avoid this issue, seems to be misstating what Cypress will do.

The existing documentation implies that the example, incorrect test cases will error and fail, while what will really happen is those test cases will succeed even if the Cypress assertions in them fail, which makes this lint rule extremely important (the former would force people to fix their test cases, the latter will lead to test cases succeeding even when they should be failing).

I suggest until cypress-io/cypress#4742 can be fixed that we update these docs to describe the actual behavior which will emphasize the importance of this rule.

If someone can confirm my understanding I may be able to make a PR for this change myself.

Feature request: Allow "body" with cypress/require-data-selectors rule

This is more of a feature request than a bug report. We use cypress/require-data-selectors in our Cypress test suite and it's helped us a lot. However, there is a case where it can be annoying.
Say you have a keyboard shortcut on the page you are testing, for example pressing "Escape" will close a modal pop-up. We'll write a cypress test like this:

cy.get("body").type("{esc}");

But this is flagged as an error by cypress/require-data-selectors. However I would argue that adding a data-selector on <body> is kind of counter-productive, as HTML spec specifies that:

In conforming documents, there is only one body element.

Since there can be only one <body> in my document, why should I identify it with another data-attribute ?
Therefore I propose to make an exception and allow cy.get("body") with this rule. Currently, we are "working around" the errors by using aliases so that the error will only have to be disabled once instead of everywhere on the page:

// eslint-disable-next-line cypress/require-data-selectors
cy.get("body").as("body");
//...
cy.get("@body"); // Aliases are allowed

What do you think about that ?
I can write a pull request for that if you agree with the proposal.

Have a nice day ! :)

Error Rule does not apply when you are using page objects

Hello team,
I'm using eslint-plugin-cypress and I defined the rule 'cypress/no-force': 'error'm but if I have a Page object that executes a click, I can use the ({force: true}) without any error
adminPage.objectToClick().click({ force: true })
Is there any way to fix that?

Add globals variables to recommended config

Jest ESLint plugin does a nice thing and adds it's globals into the recommended configuration so you can just do

module.exports = {
  extends: [
    'plugin:jest/recommended',
  ],
};

and you are all setup and ready.

Do you think you can do that too? You are already adding both the plugin and the rules, and the 3 of them will be used together in most scenarios.

require-data-selectors rule does not recognise backticks

I'm using template literals in some steps (as I use cucumber-preprocessor), so I have some data selectors encapsulated in backticks, like for example as follows:

cy.get(`[data-test="field:${name}"]`);

As far as I can see, there's no way to make the rule work with backticks; would be cool to have this feature.

Thanks!

Add cypress/recommended config failed with eslint 4.X

{
   extends: [
       'plugin:cypress/recommended'
   ]
}

is the new feature after Release 2.1.0
and the dependency said it requires peerDependencies: { eslint: '>= 3.2.1' }

When I use eslint 5.9.0 and add this config, everything is fine.
However, when I use eslint 4.6.1, it throw

Cannot read property 'replace' of undefined
TypeError: Cannot read property 'replace' of undefined

at messages.map.message (/Users/Sean/Desktop/ocr/frontend-src/node_modules/eslint/lib/formatters/stylish.js:68:36)
at Array.map (native)
at results.forEach.result (/Users/Sean/Desktop/ocr/frontend-src/node_modules/eslint/lib/formatters/stylish.js:53:22)
at Array.forEach (native)
at module.exports (/Users/Sean/Desktop/ocr/frontend-src/node_modules/eslint/lib/formatters/stylish.js:38:13)
at printResults (/Users/Sean/Desktop/ocr/frontend-src/node_modules/eslint/lib/cli.js:90:20)
at Object.execute (/Users/Sean/Desktop/ocr/frontend-src/node_modules/eslint/lib/cli.js:193:17)
at Object.<anonymous> (/Users/Sean/Desktop/ocr/frontend-src/node_modules/eslint/bin/eslint.js:74:28)
at Module._compile (module.js:570:32)
at Object.Module._extensions..js (module.js:579:10)

It only works if I remove the config plugin:cypress/recommended

VSCode: Cannot read property 'recommended' of undefined

I followed the install steps for this plugin as outlined in the readme.

Upon adding "plugin:cypress/recommended" to the "extends" block of .eslintrc, i get the following error:

screen shot 2019-01-21 at 2 23 48 pm

Digging deeper, i see:
screen shot 2019-01-21 at 2 27 55 pm

I'll gladly provide any additional info you may need...im out of ideas on where to dig...

Thanks!!

Add Rule: Error if `.only` is found in tests.

We've had a few times where we commit a .only in the specs. I figured it could be a linting rule so it doesn't make it into a master branch for projects that have lint checks in their CI pipeline or GH actions.

I'm willing to add this myself if people think it's a good idea.

no-assigning-return-values: TypeError: Cannot read property 'callee' of undefined

TypeError: Cannot read property 'callee' of undefined
  at isCypressCommandDeclaration (C:\git\test\node_modules\eslint-plugin-cypress\lib\rules\no-assigning-return-values.js:38:17)
  at Array.some (<anonymous>:null:null)
  at VariableDeclaration (C:\git\test\node_modules\eslint-plugin-cypress\lib\rules\no-assigning-return-values.js:24:31)

I'll try and make a PR if I can get to the bottom of it.

Make the require-data-selectors rule customizable

Today
We can activate this rule, and confiure if warn or error

Proposal
It would be nice to be able to add an optinal second argument to the rule, specifying the attribute name.
It could be :
"cypress/require-data-selectors": {"warn","data-qa"}
Or :
"cypress/require-data-selectors": ["warn","attr-qa"]

This would have the following behaviour

  • If not specified, today behavoiur (data-* is ok, anything else is KO)
  • If specified it is used as it (selector should start with [parameter, such as [data-qa *= or [attr-id-test $= or ...)

This would allow team to check it's not based on [data-ga for ex, but also to allow for people using dedicated attributes, but not following w3c (attr-* instead of data-*) to still take advantage of this rule.

Show an errror when using arrow functions with hooks

Hi,

Today I've tried to use this.skip() inside before() it() but it didn't work because I was using arrow functions instead of normal functions and so this was undefined.

It took me some time before being able to make this.skip() works, and I think creating a rule can save time from other people too.

This rule would be recommended and will throw an error when using arrow functions with :

  • describe, context
  • it, it.skip, it.only, ... specify
  • before/beforeEach
  • after/afterEach

What do you think? I can open a PR for this rule (I've never write an ESLint rule but it does not seems really complicated)

Thanks!

error: no-assigning-return-values: Do not assign return value of Cy command

I just added the eslint-plugin-cypress to the Cypress documentation. So now our linter is running against our examples in our documentation.

There are some examples we have in the docs that are erroring in the eslint-plugin, which I have to think should not be erroring since they are recommended uses of cypress. Can we make this rule exclude assignments of cy.spy or cy.stub?

  1. error cypress/no-assigning-return-values: Do not assign the return value of a Cypress command There are other examples in stub as well like const stub = cy.stub()
    https://docs.cypress.io/api/commands/spy.html#Aliases
const obj = {
  foo () {}
}
const spy = cy.spy(obj, 'foo').as('anyArgs')
const withFoo = spy.withArgs('foo').as('withFoo')

obj.foo()
expect(spy).to.be.called
expect(withFoo).to.be.called // purposefully failing assertion

no-unnecessary-waiting: TypeError: Cannot read property 'null' of undefined

using [email protected]

2.8.1 works fine, but 2.9.0 throws an error on

      cy.login(adapterUser).wait(5000)
TypeError: Cannot read property 'null' of undefined
Occurred while linting /Users/ggp/dev/tw-git/saas-ui/cypress/integration/systems/settings.systems.datasource.connect.request.negative.spec.js:24
    at isIdentifierNumberConstArgument (/Users/ggp/dev/tw-git/saas-ui/node_modules/eslint-plugin-cypress/lib/rules/no-unnecessary-waiting.js:76:39)
    at CallExpression (/Users/ggp/dev/tw-git/saas-ui/node_modules/eslint-plugin-cypress/lib/rules/no-unnecessary-waiting.js:27:15)
    at /Users/ggp/dev/tw-git/saas-ui/node_modules/eslint/lib/linter/safe-emitter.js:45:58
    at Array.forEach (<anonymous>)
    at Object.emit (/Users/ggp/dev/tw-git/saas-ui/node_modules/eslint/lib/linter/safe-emitter.js:45:38)
    at NodeEventGenerator.applySelector (/Users/ggp/dev/tw-git/saas-ui/node_modules/eslint/lib/linter/node-event-generator.js:254:26)
    at NodeEventGenerator.applySelectors (/Users/ggp/dev/tw-git/saas-ui/node_modules/eslint/lib/linter/node-event-generator.js:283:22)
    at NodeEventGenerator.enterNode (/Users/ggp/dev/tw-git/saas-ui/node_modules/eslint/lib/linter/node-event-generator.js:297:14)
    at CodePathAnalyzer.enterNode (/Users/ggp/dev/tw-git/saas-ui/node_modules/eslint/lib/linter/code-path-analysis/code-path-analyzer.js:634:23)
    at /Users/ggp/dev/tw-git/saas-ui/node_modules/eslint/lib/linter/linter.js:936:32
error Command failed with exit code 2.

Don't allow assigning return values to objects

I have a team that's started writing Cypress like:

context('Foo', () => {
  const scope = {}
  it('allows this', () => {
    scope.baddie = cy.get('it')
  })
  ...
})

I was expecting no-assigning-return-values to error out on the assignment of a cypress command to scope.baddie.

const scope = {} is also discouraged by Cypress's Docs, but that's another issue.

Feature request: Disallow describe.only and it.only

According to the Cypress docs, one recommended way to write tests is to temporarily use describe.only and/or it.only to only run the single test currently being written.

If I understand the concept correctly, these two functions are useful while writing tests, but should never be committed to version history. However, that happens way to easily by accident, if we forget to remove the .only part. I therefore propose a new rule to disallow these functions entirely. (.skip probably shouldn't be included here, as it makes sense to commit an incomplete test.)

`no-unnecessary-waiting` rule does not work in command chain

When writing the following the rule does not recognise the error:

// Does not throw lint error
cy.get('foo').wait(100);
// Does not throw lint error
cy.anyCommand()
  .wait(100);

It seems like the rule only works when .wait() is called as a parent command:

// Throws lint error
cy.wait(100);

I think the issue is located here https://github.com/cypress-io/eslint-plugin-cypress/blob/master/lib/rules/no-unnecessary-waiting.js#L35

In fact, the implementation here is accurate when you look at the documentation, but not when you look at the source code for the .wait() command.

I'll also open an issue over at cypress-documentation about this mismatch.

Legit assertions fail with eslint

Hello!

I'm using eslint-plugin-cypress 2.0.1 and babel-eslint 8.2.6

expect(null).to.be.null fails with Expected an assignment or function call and instead saw an expression

If I change it to:
expect(null).to.eq(null) <- works ok

Thanks!

package script helper

  • what would be a recommended script to add to run lint
  • also is lint fix supported

e.g. for vue cli I can add these scripts then run npm run lint or npm run lint:fix

package.json

{
   "scripts": {
        "lint": "vue-cli-service lint",
        "lint:fix": "vue-cli-service lint --fix"
    }
}

Selector rule doesn't work with helper functions

Hi -- I can't get the require data selectors rule to work with a helper function:

e.g.

export const getTestId = (id: string) => `[data-testid="${id}"]`;

getTestId('headernav');

will there be functionality to support this?

thanks!

Suggestion: Loosen or Reconsider the `no-unnecessary-waiting` Rule

So I just recently started trying out Cypress; and with the help of Cypress Testing Library, life has been pretty simple. Unfortunately, after writing my first few tests, I came to learn that ESLint complains when passing a number to cy.wait (when using cypress/recommended).

I read the documentation, and it most definitely makes sense! 😄 But I think it also makes the dangerous assumption that these are the only reasons people could conceivable use cy.wait. Actually, all of the warnings in the documentation are for people who misunderstand how Cypress [resolution] works altogether. People who already know how Cypress resolves would never run into these problems. So it seems less like a cy.wait issue and more like an issue with understanding Cypress.

My problem is that the rule (and its documentation) gives no solution for the following use case: After the user performs an action, a toast message appears. This message disappears after the allotted time (if not interacted with). With Cypress Testing Library, this might look like:

const toastMessage = "My toast message";
const toastTime = 5000;

/* Imagine user actions are here */

cy.findByText(toastMessage).should("exist");
cy.wait(toastTime);
cy.findByText(toastMessage).should("not.exist");

I think there are 2 potentially better options:

1a) Let the Rule Pass When a Variable Is Used

When a person provides a specific variable denoting the allotted wait time, it helps clarify intent (as in the toast example I showed). This (theoretically) suggests that the wait time is not merely "arbitrary".

1b) Let the Rule Pass When a Variable Is Used, but Only As a Rule Option

Same as the previous one. However, instead of making it the default case, it enables people to opt-in for allowing variables via a rule option.

2) Remove the Rule Altogether

This is a very peculiar option. But the reason I consider this an option is because the documentation doesn't provide a strong case for not using cy.wait(Number). Most of the time, lint rules provide strong arguments by discussing code readability, minimization of code lines, minimization of confusion, improved consistency, etc. Here, the only argument is that people need to know how Cypress resolution works; but they should be doing that anyway.

Whether or not people understand Cypress resolution is a separate matter from how people should or shouldn't be using cy.wait. Under the cy.wait documentation, the description would do much better to display the valid use cases for the function instead of only saying what should never be done. This enables developers to understand the intent of cy.wait, and it will likely decrease the number of people who create janky workarounds for what they consider their valid use cases that lack in-documentation examples.

Errors when assigning cy.spy() return value

Since cypress/no-assigning-return-values is enabled and in the "recommended" ruleset, we get

error Do not assign the return value of a Cypress command

for code that uses cy.spy() synchronously e.g.

const nameSpy = cy.spy(user, 'setName')

From the docs:

Unlike most Cypress commands, cy.spy() is synchronous and returns a value (the spy) instead of a Promise-like chain-able object.

I believe there are at two possible options here: either allow the rule to exclude cy.spy assignments in particular, or update the docs to declare that using return value is deprecated in favor of aliasing + change the linter error message to include such a recommendation IF indeed works / it actually does return a chainable.

ESLint couldn't find the plugin "eslint-plugin-cypress"

When using VSCODE plugin or globally via eslint /Users/jeffbeltran/work/lassie/cypress/integration/sample_spec.j

output:

Oops! Something went wrong! :(

ESLint: 5.13.0.
ESLint couldn't find the plugin "eslint-plugin-cypress". This can happen for a couple different reasons:

1. If ESLint is installed globally, then make sure eslint-plugin-cypress is also installed globally. A globally-installed ESLint cannot find a locally-installed plugin.

2. If ESLint is installed locally, then it's likely that the plugin isn't installed correctly. Try reinstalling by running the following:

    npm i eslint-plugin-cypress@latest --save-dev

Path to ESLint package: /usr/local/lib/node_modules/eslint

Plugin not working in cypress standalone project with Typescript

I have a Cypress 9.0 standalone project (not included inside a main app project), using Typescript.
I followed the instructions to install the plugin

  • npm install eslint -D
  • npm install eslint-plugin-cypress -D
  • create a .eslintrc.json in the cypress root folder with the following content
{
  "extends": [
    "plugin:cypress/recommended"
  ]
}

Restarted VSCode... but when I put a cy.wait(1000) in any test, it doesn't yell at me.. I even tried adding the rules to the json file as it indicated the documentation, but nothing

What am I missing?

Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.