Cypress causing type errors in jest assertions
Asked Answered
D

21

117

I had been using react-testing-library as well as @testing-library/jest-dom/extend-expect. I installed Cypress yesterday, and now I'm getting Typescript errors on all my jest matchers:

Property 'toEqual' doesn't exist on type 'Assertion'. Did you mean 'equal'?

It looks like it's getting the type of expect from the wrong assertion library or something? Also, expect(...).to.equal(...) doesn't even work either.

I actually tried installing @types/jest and yarn appears to have succeeded but it's not listed in my package.json's devDependencies.

Here's my tsconfig

{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "noImplicitAny": false,
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": false,
    "noEmit": true,
    "jsx": "react",
    "skipDefaultLibCheck": true,
    "types": [
      "node",
      "cypress",
      "jest"
    ]
  },
  "include": [
    "src"
  ]
}

I'll also mention that all my cy calls in my cypress tests are getting a cy is not defined error from ESLint.

Diarthrosis answered 22/11, 2019 at 17:28 Comment(1)
Since Cypress v10 the main cause of the error is ./cypress.config.ts. Consider to try Marcus Fonseca's answer firstNewsprint
P
80

I ran into this problem yesterday. It seems that what you are saying is correct, cypress and jest both declares types for expect. In this case the cypress declaration seem to be the one that is picked up. Here's an issue from the cypress repo regarding this:

https://github.com/cypress-io/cypress/issues/1603

The solution mentioned in there worked for me. You need to exclude the jest spec files from in tsconfig.json and then declare a tsconfig.spec.json where they are explicitly included again.

tsconfig.json:

{
  ...,
  "exclude": [
    "**/*.spec.ts"
  ]
}

tsconfig.spec.json:

{
  "extends": "./tsconfig.json",
  "include": [
    "**/*.spec.ts"
  ],
  ...
}

With this in place, both my (angular 8) app compiles fine and I can run the jest tests without issue. Here's another example mentioned in the issue with a similar fix being implemented:

https://github.com/neiltownsley/react-typescript-cypress/pull/1/files#diff-e5e546dd2eb0351f813d63d1b39dbc48R29

NOTE 9 Mar 2023: Since Cypress v10 the main cause of the error is ./cypress.config.ts. Consider to try Marcus Fonseca's answer first

Phosphoprotein answered 6/12, 2019 at 9:38 Comment(6)
Do you mean the Cypress .spec files?Argal
@Argal Sorry if it is unclear from the text above. The base tsconfig.json excludes the jest .spec files, and then the tsconfig.spec.json (that jest uses) includes them. For this to work, we're assuming you Cypress tests are not in files named *.spec.ts. Does that answer your question?Phosphoprotein
This also worked when dealing with the same issue between Cypress + Jasmine in an Angular workspace. Thanks!Pontonier
This problem goes into Karma/Jasmine in Angular. My solution was to close all *.spec.ts files and do the exclude/include. It seems that Angular-files needs a "re-boot" to get the changes correct.Brocatel
This approach has drawback with VSCODE hints. VSCODE uses typescript server, which will not work with two tsconfig files. Better approach in this case will be go with import { expect } from '@jest/globals';Emulation
Works for me! I was looking for working solution between cypress component testing and jasmine unit testing in one directory.Bodleian
S
80

Anyone facing this problem in the github issue "New Cypress 10 global TypeScript type conflicts with Jest expect" has a workaround

Fix issue by exluding ./cypress.config.ts in your tsconfig.json

"exclude": [
  "./cypress.config.ts",
  //other exclusions that may help https://github.com/cypress-io/cypress/issues/22059#issuecomment-1428298264
  "node_modules",
  "cypress",
  "**/*.cy.tsx"
]

From cypress developer:

We didn't change our globals very much for v10. For all the cases I reproduced, it was fixed by adding ./cypress.config.ts to the tsconfig.exclude property. Since the cypress.config.ts is being included in the type checking, it is loading the cypress types which is polluting your jest tests.

Surety answered 17/6, 2022 at 18:40 Comment(4)
This! And I also had to "exclude" all my cypress test files in my eslint config, because those files also include "cypress" which pollutes the jest typings.Predestinate
I believe this should be the accepted answer.Craunch
I'm getting Cannot find name 'cy'.Slyke
I also get the "Cannot find name 'cy' in all my cypress test now.Equanimous
N
71

There is an official Cypress repo that shows how to fix this exact problem https://github.com/cypress-io/cypress-and-jest-typescript-example

I wasn't able to get that method to work in one of my projects, so I am using this as a workaround:

import { expect } from '@jest/globals';
Nonconformist answered 5/12, 2020 at 4:53 Comment(4)
I have followed the official Cypress repo. Thanks for the link.Requiescat
This was the only thing working for me, it would be nice to have it solved properly though :/.Eyewitness
After exhausting my entire list of expletives, the link to the cypress-and-jest-typescript-example in the official Cypress repo referenced in this answer finally worked for my Angular 15 + Cypress 12 project. The only difference was in tsconfig.json, where I changed the "exclude" to ["src/*.spec.ts"]Alyworth
Same, none of the config shenanigans worked as it was importing cypress straight from node_modules even if there was no cypress folder with test specs. But this is madness and not a real solution.Aye
T
27

Finally I found the solution! Just add "cypress" to the exclude property of your main tsconfig.json:

{
  ...YOUR_CONFIGS,
  "compilerOptions": {
    ...YOUR_CONFIGS,
    "typeRoots": [ // THIS TO GET ALL THE TYPES
      "node_modules/@types"
    ],
  },
  "exclude": ["cypress"], 
}

You should add also another tsconfig.json for your cypress tests. You can create a cypress folder and add that tsconfig.json there. The following is my Cypress tsconfig.json:

{
  "compilerOptions": {
    "strict": true,
    "baseUrl": "../node_modules",
    "target": "es5",
    "lib": ["es5", "dom"],
    "types": ["cypress", "@testing-library/cypress"]
  },
  "include": ["./**/*.ts"]
}
Tetrastich answered 16/11, 2021 at 13:52 Comment(2)
Great suggestion with the exclude:[cypress], that did the trick for me.Grained
This should be the accepted answer. Also exclude cypress.config.ts if you have that as well.Astrogeology
Q
16

This worked for me in my tsconfig.json

I had to add

  "include": ["src/**/*"],

Complete code here

{
  "compilerOptions": {
    "outDir": "./dist/",
    "noImplicitAny": true,
    "module": "commonjs",
    "target": "es5",
    "jsx": "react",
    "allowJs": true,
    "allowSyntheticDefaultImports" : true,
    "esModuleInterop" : true,
    "sourceMap": true,
    "experimentalDecorators": true
  },
  "include": ["src/**/*"],
  "exclude": [
    "node_modules",
    "**/*.spec.ts"
  ]
}
Qualified answered 16/5, 2020 at 15:58 Comment(1)
That was the key for me too. adding src/** in the root tsconfig.json solved it after looking at the other settings in the example repo: github.com/cypress-io/cypress-and-jest-typescript-example.Antihero
A
13

There are several cases that cause this issue. In my case, It was fixed by adding ./cypress.config.ts to the tsconfig.exclude property. Since the cypress.config.ts is being included in the type checking, it is loading the cypress types which is polluting your jest tests. I believe it will help you if you are using typscript for cypress configuration.

Ansell answered 17/6, 2022 at 20:30 Comment(2)
Wondering if there is a way to keep it included but not cause that issue.Twin
Okay, seems like this is the only possible solution since Cypress v10. They suggest excluding cypress.config.ts and including it in the <root>/cypress/tsconfig.ts (if you're using separated tsconfig for Cypress ofc) instead. github.com/cypress-io/cypress/issues/22059Twin
T
12

There are three steps to make it disappear.

  1. In your /cypress/ directory add tsconfig.json.

  2. Paste the following content as in this example:

    {
        "extends": "../tsconfig.json",
        "compilerOptions": {
           "noEmit": true,
           "types": ["cypress"]
        },
        "include": [
            "../node_modules/cypress",
            "./**/*.ts"
        ]
    }
    
  3. In your original tsconfig.json add

    {
      ...
      "exclude": ["cypress"]
      ...
     }
    

to the top level configuration. That's it.

A few extra notes:

  1. If your cypress/tsconfig.json complains about include, exclude you may need to overwrite their values as they are inherited from the original file. In my case adding

    "exclude": [],
    

    ...has solved the problem.

  2. May be trivial but remember to use .ts extension to files for your spec from now on.

Trinatrinal answered 24/2, 2022 at 9:3 Comment(1)
Adding "exclude": [] solved my issue too, excellent suggestionBertolde
R
5

The simplest way for solving this issue is to add this line to tsconfig.json:

  "include": [
    "src/**/*.ts"
  ],

I am attaching my tsconfig file for better understanding. You can see the addition in lines 3-5.

{
  "compileOnSave": false,
  "include": [
    "src/**/*.ts"
  ],
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "downlevelIteration": true,
    "experimentalDecorators": true,
    "module": "esnext",
    "moduleResolution": "node",
    "importHelpers": true,
    "target": "es2015",
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2018",
      "dom"
    ]
  },
  "angularCompilerOptions": {
    "fullTemplateTypeCheck": true,
    "strictInjectionParameters": true
  }
}
Repugn answered 17/7, 2021 at 12:9 Comment(1)
Thank you! Worked for me in an Ionic app with jasmine/cypress. I needed to close Visual Studio Code and reopen it.Douglassdougy
A
4

I came across the same problem and after trying the above options, a combination two solutions worked. Adding below to test file

import { expect } from '@jest/globals';.

and this one to tsconfig.json(included to stop jest @types errors)

{ "include": [
    "**/*.spec.ts"
  ] 
}
Antiproton answered 19/1, 2022 at 20:36 Comment(1)
It works fine but I didn't have to update may tsconfig.sjonWarmth
S
2

In my case it helps the only one thing: adding "types": ["jest"] to "compilerOptions":

{
  "compilerOptions": {
    ...
    "types": ["jest"],
   ...
  },     
}
Stearne answered 29/7, 2020 at 20:0 Comment(0)
A
1

In tsconfig.json add the following,

"exclude": ["src/**/*.spec.ts"]

In tsconfig.spec.json add the following

"exclude": [""],

"include": ["src//*.spec.ts", "src//*.d.ts"]

Alceste answered 5/12, 2022 at 9:52 Comment(0)
B
1

I had same problem. In Angular project I was using Jasmine for Unit Tests (UT) and Cypress for End-to-end tests (e2e), but I wanted to use component testing too. I had got problem with Jasmine and Mocha typings. I solved problem with Typescript references in tsconfig.json.

I was based on Github comment

tsconfig.json (part)

"include": ["src"],
"references": [{ "path": "./tsconfig.app.json" }, { "path": "./tsconfig.spec.json" }, { "path": "./tsconfig.cy.json" }]

tsconfig.spec.json

{
"extends": "./tsconfig.json",
"compilerOptions": {
    "baseUrl": "./src",
    "types": ["jasmine"],
    "composite": true,
    "declaration": true
},
"files": ["testing/jest-global-mocks.ts"],
"include": ["app/**/*.spec.ts"],
}

tsconfig.cy.json

{
"extends": "./tsconfig.json",
"compilerOptions": {
    "composite": true,
    "declaration": true
},
"include": ["src", "cypress", "node_modules/cypress"],
"exclude": ["**/*.spec.ts"],
}
Bodleian answered 30/6, 2023 at 10:49 Comment(0)
A
1

Since I used ng add @cypress/schematic to set up Cypress, my cypress/tsconfig.json file had this line in it:

"extends": "../tsconfig.json",

./tsconfig.json was trying to exclude the same files that ./cypress/tsconfig.json was trying to include, which created the conflict. To solve the problem:

  1. Remove "extends": "../tsconfig.json" from cypress/tsconfig.json
  2. Add "include": ["**/*.cy.ts"] to cypress/tsconfig.json
  3. Per Marcus' answer, to ./tsconfig.json, add:
"exclude": [
  "./cypress.config.ts",
  "node_modules",
  "cypress"
]
Alanalana answered 12/9, 2023 at 20:17 Comment(0)
P
1

For me the problem originated with the use of @testing-library/cypress. According to the documentation you need to add the below to your tsconfig.json and that causes the problem.

{
  "compilerOptions": {
    "types": ["cypress", "@testing-library/cypress"]
  }
}

Creating a ./cypress/tsconfig.json with the above instead of having it in ./tsconfig.json did the trick.

Phonograph answered 1/2 at 9:29 Comment(0)
R
0

I came across this issue today also - what caused it was moving my Cypress folder from / to src/test. I moved it back to avoid the conflict.

Right answered 27/7, 2021 at 12:8 Comment(0)
D
0

I had the same problem with Next.js app. This tsconfig.json works for me:

{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true,
    "types": ["cypress", "node", "jest"]
  },
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
  "exclude": ["node_modules", "**/*.spec.ts"]
}

Dashed answered 4/8, 2022 at 9:48 Comment(0)
P
0

After reading through the answers above, I preferred to just rename the Cypress files to their current naming convention, so eslint doesn't consider them Jest files in the first place.

Here's the process I used to make the change.


1. Rename all tests:

My-Cypress-Test.spec.js becomes My-Cypress-Test.cy.js

WARNING: THIS IS A RECURSIVE COMMAND, SO ANY MATCHING FILES IN ANY SUBDIRECTORY WILL BE AFFECTED

find ./**/cypress/** -name '*.spec.js' -exec sh -c 'mv "$0" "${0%.spec.js}.cy.js"' '{}' \;      

This command assumes that your cypress tests are in the default folder name "cypress".

If that's not the case, modify the command below to reflect that, or just cd to your cypress test directory and run it against ./


2. Update your Cypress config to match against the new file extensions (if needed)

In cypress.config.js:

replace specPattern: "./cypress/integration/**/**/*.spec.js",

with specPattern: "./cypress/integration/**/**/*.cy.js",


3. (Optional): Ensure git treats this process as a rename

I've noticed that git tends to consider the old file as deleted and the newly renamed file as a new file, which can break your file history / git blame, etc.

I fix this by simply running git add . in any parent directory of the renamed files.

Pigeonhearted answered 24/2, 2023 at 10:34 Comment(0)
T
0

I had the same issue, and the solution is as easy as it sounds: just follow the official tutorial: https://docs.cypress.io/guides/tooling/typescript-support#Configure-tsconfigjson

  1. Do not add anything related to cypress in your root tsconfig
  2. Create new tsconfig in cypress folder as shown in the tutorial (copy-paste)
  3. Enjoy
Towny answered 3/3, 2023 at 13:53 Comment(0)
D
0

You can find out about the conflict between Jest and Cypress in the link to the documentation: https://docs.cypress.io/guides/tooling/typescript-support#Clashing-types-with-Jest

Example of a proposed solution: https://github.com/cypress-io/cypress-and-jest-typescript-example

Drawing answered 13/4, 2023 at 14:55 Comment(0)
H
-1

I had the same problem with cypress + jasmine and nothing would help.

Finally, I ended with copying the jasmine expect declaration and putting it in a new file /test/global.d.ts:

declare function expect<T>(actual: T): jasmine.Matchers<T>;

Might be worth mentioning that in my tsconfig.json the folder is explicitly included as follows:

{
    "include": ["test/**/*", ...]
}

This caused yet another shadowing of the dreaded cypress and silenced the compilator.

Hexastyle answered 18/8, 2021 at 7:46 Comment(0)
U
-1

Renaming cypress.config.ts to cypress.config.js will fix the problem since TypeScript no longer picks the file up.

I had another issue with Cypress that was also solved by the file ending update.

Now, this might have other side-effects I'm not considering. This was just the quickest and simplest solution to the issues we were facing right now.

Ubiquitarian answered 16/4 at 7:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.