Jest assertions encountering type errors due to Cypress

After using react-testing-library and

@testing-library/jest-dom/extend-expect
, I decided to install Cypress. However, I now face Typescript errors on all my jest matchers:

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

It seems like the type of expect is being pulled from the wrong assertion library or something. Even expect(...).to.equal(...) isn't working as expected.

I attempted to install @types/jest, yarn seemed to have succeeded but it's not showing up in my package.json's devDependencies.

Below is a snippet of 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"
  ]
}

Additionally, I'm encountering an issue where all my cy calls in my cypress tests are flagging a cy is not defined error from ESLint.

Answer №1

Yesterday, I encountered a puzzling issue where both Cypress and Jest were declaring types for expect. It seems that the declaration from Cypress was being prioritized. There's an interesting discussion on this matter in a GitHub issue on the Cypress repository:

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

The solution provided there resolved the problem for me. By excluding jest spec files in the tsconfig.json and then explicitly including them in a separate tsconfig.spec.json, the issue was mitigated.

Here's how you can set up the configurations:

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

tsconfig.spec.json:

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

Following this setup, my Angular 8 application compiled successfully, and running Jest tests posed no issues. Another example mentioned in the same GitHub issue demonstrated a similar approach to fixing the problem:

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

Note: As of Mar 9, 2023, with Cypress v10, the main cause of the error is attributed to ./cypress.config.ts. You may want to explore Marcus Fonseca's suggested solution first.

Answer №2

If you're encountering the issue mentioned in the GitHub problem "New Cypress 10 global TypeScript type conflicts with Jest expect", there is a workaround available.

To resolve this problem, simply exclude ./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"
]

A developer from Cypress suggests:

We haven't made significant changes to our globals for version 10. Based on my testing, most cases were resolved by adding ./cypress.config.ts to the tsconfig.exclude property. Including cypress.config.ts in type checking loads the cypress types, causing interference with jest tests.

Answer №3

Need help fixing a specific issue with Cypress? Check out the official Cypress repository for step-by-step solutions: https://github.com/cypress-io/cypress-and-jest-typescript-example

If you're like me and that method didn't work for your project, here's a workaround I found helpful:

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

Answer №4

Success! I've discovered the solution at last. Simply insert "cypress" into the exclude section of your primary tsconfig.json:

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

Additionally, don't forget to set up a separate tsconfig.json for your cypress tests. Set up a cypress folder and place the new tsconfig.json inside. Here's an example of my Cypress tsconfig.json:

{
  "compilerOptions": {
    "strict": true,
    "baseUrl": "../node_modules",
    "target": "es5",
    "lib": ["es5", "dom"],
    "types": ["cypress", "@testing-library/cypress"]
  },
  "include": ["./**/*.ts"]
}

Answer №5

Here is the solution I found for my tsconfig.json file:

I made the following addition:

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

For the complete code implementation, see below:

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

Answer №6

There are various scenarios that may lead to the above-mentioned problem. In my personal experience, the issue was resolved by including ./cypress.config.ts in the tsconfig.exclude property. By excluding this file from type checking, it prevents the cypress types from interfering with your jest tests. I suggest trying this approach if you are utilizing TypeScript for your cypress configuration.

Answer №7

To make it vanish, follow these three steps.

  1. Create a tsconfig.json file in your /cypress/ directory.

  2. Copy and paste the code from this example:

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

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

This simple configuration should do the trick!

A couple of extra things to note:

  1. If you encounter issues with include, exclude in your cypress/tsconfig.json, try adding:

    "exclude": [],
    

    This might resolve any problems you face.

  2. Don't forget to use the .ts extension for your spec files going forward.

Answer №8

To resolve this issue effectively, simply insert the following line into your tsconfig.json file:

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

If you refer to my attached tsconfig file, you will find the mentioned addition on 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
  }
}

Answer №9

I encountered a similar issue and after experimenting with various solutions, I found that a combination of two approaches did the trick. I added the following code snippet to my test file:

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

Additionally, I included the following configuration in my tsconfig.json file to prevent jest @types errors:

{ "include": [
    "**/*.spec.ts"
  ] 
}

Answer №10

For me, the solution was simple: including

"types": ["jest"]
in the "compilerOptions":

{
  "compilerOptions": {
    ...
    "types": ["jest"],
   ...
  },     
}

Answer №11

To configure the tsconfig.json file, insert the following:

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

For the tsconfig.spec.json, include the following:

"exclude": [""],

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

Answer №12

After utilizing the ng add @cypress/schematic command to configure Cypress, I came across this particular line in my cypress/tsconfig.json file:

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

It became evident that ./tsconfig.json and ./cypress/tsconfig.json were conflicting with each other since they had contradictory directives regarding file inclusion and exclusion. To rectify this issue, I followed these steps:

  1. Delete
    "extends": "../tsconfig.json"
    from cypress/tsconfig.json
  2. Include
    "include": ["**/*.cy.ts"]
    in cypress/tsconfig.json
  3. In accordance with Marcus' answer, update ./tsconfig.json as follows:
"exclude": [
  "./cypress.config.ts",
  "node_modules",
  "cypress"
]

Answer №13

My troubleshooting journey began when I started using @testing-library/cypress. Upon reviewing the documentation, it was recommended to include certain configurations in the tsconfig.json. However, this led to unexpected issues.

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

To resolve the problem, I moved these configurations to a separate ./cypress/tsconfig.json file instead of keeping them in the main ./tsconfig.json.

Answer №14

While working on an Angular project, I encountered a similar issue. I was utilizing Jasmine for Unit Tests (UT) and Cypress for End-to-end tests (e2e), but I also wanted to incorporate component testing into my workflow. However, I ran into difficulties with the typings for Jasmine and Mocha. To resolve this issue, I utilized Typescript references in the tsconfig.json.

This solution was inspired by a helpful Github comment

Snippet from tsconfig.json:

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

Snippet from 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"],
}

Snippet from tsconfig.cy.json:

{
"extends": "./tsconfig.json",
"compilerOptions": {
    "composite": true,
    "declaration": true
},
"include": ["src", "cypress", "node_modules/cypress"],
"exclude": ["**/*.spec.ts"],
}

Answer №15

Today, I encountered a similar issue when I relocated my Cypress folder from the root directory to src/test. To resolve the conflict, I ended up moving it back.

Answer №16

I encountered a similar issue while working on my Next.js app. After some troubleshooting, I found that this configuration in tsconfig.json resolved the problem 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"]
}

Answer №17

Having reviewed the solutions provided earlier, I decided to opt for a different approach by changing the file names in Cypress to adhere to their current naming convention, preventing them from being mistaken as Jest files from the beginning.

Below outlines the steps I took to implement this adjustment.


1. File renaming:

My-Cypress-Test.spec.js will now be known as My-Cypress-Test.cy.js

DISCLAIMER: THIS COMMAND WILL AFFECT ALL FILES WITH SIMILAR NAMES IN ANY SUBDIRECTORY

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

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

If this is not the case, adjust the command accordingly or navigate to the cypress test directory and execute it using ./


2. Updating Cypress configuration to account for new file extensions (if necessary)

In cypress.config.js:

replace

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

with

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


3. (Optional): Ensuring git recognizes this as a file rename

I have observed git often treats the old file as deleted and the renamed file as new, potentially disrupting file history / git blame, etc.

To address this, simply execute git add . in any parent directory of the renamed files.

Answer №18

I encountered the same issue, but I found a simple solution that worked like a charm: just follow the official tutorial at https://docs.cypress.io/guides/tooling/typescript-support#Configure-tsconfigjson

  1. Avoid adding any cypress-related configurations to your main tsconfig file
  2. Follow the steps outlined in the tutorial to create a new tsconfig file within the cypress folder (simply copy and paste)
  3. Sit back and enjoy a seamless experience

Answer №20

I encountered a similar issue while using cypress with jasmine and nothing seemed to solve it.

After trying various solutions, I resorted to copying the jasmine expect declaration and placing it in a new file named /test/global.d.ts:

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

It's worth noting that in my tsconfig.json, I explicitly included the folder as follows:

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

This resolved the issue of conflicting definitions and eliminated any errors during compilation.

Answer №21

Changing the file name from cypress.config.ts to cypress.config.js should resolve the issue as TypeScript no longer recognizes the original file.

I encountered a similar problem with Cypress that was also remedied by updating the file extension.

It's possible that there may be unintended consequences of this change that I haven't anticipated. However, for now, it provided a quick and straightforward fix to our current challenges.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Leveraging private members in Typescript with Module Augmentation

Recently, I delved into the concept of Module Augmentation in Typescript. My goal was to create a module that could inject a method into an object prototype (specifically a class) from another module upon import. Here is the structure of my folders: . ├ ...

To initiate the development environment, execute the following command: `cross-env NODE_ENV=

[email protected] start /Users/ssurisettii/Documents/il-17g5-app cross-env NODE_ENV=development npm run webpack-development sh: cross-env: command not found npm ERR! code ELIFECYCLE npm ERR! syscall spawn npm ERR! file sh npm ERR! errno ENOENT npm ER ...

Attempting to locate an element within the DOM using TypeScript

I am completely new to TypeScript. I have been attempting to locate an element using a selector, but no matter what I tried, the findElement() method always returns undefined. Can someone please point out where my mistake might be? Any assistance would b ...

Ways to switch up the titles on UploadThing

Recently, I started working with the UploadThing library and encountered a situation where I needed to personalize some names within the code. Here is what I have so far: Below is the snippet of code that I am currently using: "use client"; imp ...

Issue with PrimeReact dropdown component not recognizing an array in TypeScript

Trying to incorporate the PrimeReact Dropdown component in a NextJs app with TypeScript. Encountering an error when attempting to select options from the dropdown list: "Objects are not valid as a React child (found: object with keys {name, code})" The b ...

Ways to invoke the function in a separate component

How can I use ViewChild to call a method in a different component? I have a method in the piechart component that I want to access from the app component using ViewChild. In my piechart.component.ts file: export class PiechartComponent { constructor() ...

Using jQuery in Angular, you can add a div element to hidden elements by appending

So, I have a hidden div that I want to show on button click. And not only do I want to show it, but I also want to append another div to it. The show and hide functionality is working fine, but the appending part seems tricky when dealing with hidden eleme ...

The issue encountered is: "Unable to assign property 'id' to a numeric value of '1' in Angular."

In my Angular 7 project, I am trying to establish a client-side request to the server-side. Below is the structure of the request that needs to be sent. { "title" : "Test Title", "user": { "id" : 7 ...

Terminating a function during execution in JavaScript/TypeScript

Currently, I am in the process of developing a VSCODE extension using TypeScript. Within this extension, there is a particularly large function that is frequently called, but only the final call holds significance. As a solution, I am attempting to elimina ...

How can I dynamically insert a variable string into a link tag using React and TypeScript?

I am just starting out with javascript and typescript, and I need to generate a link based on certain variables. I am currently facing an issue trying to insert that link into <a href="Some Link"> Some Text </a> Both the "Some Text" and "Som ...

Adding the expiry date/time to the verification email sent by AWS Cognito

After some investigation, I discovered that when a user creates an account on my website using AWS Cognito, the verification code remains valid for 24 hours. Utilizing the AWS CDK to deploy my stacks in the AWS environment, I encountered a challenge within ...

Is it possible to use a single type predicate for multiple variables in order to achieve type inference?

Is there a way to optimize the repeated calls in this code snippet by applying a map to a type predicate so that TSC can still recognize A and B as iterables (which Sets are)? if(isSet(A) && isSet(B)) { ...

Warning: Typescript is unable to locate the specified module, which may result

When it comes to importing an Icon, the following code is what I am currently using: import Icon from "!svg-react-loader?name=Icon!../images/svg/item-thumbnail.svg" When working in Visual Studio Code 1.25.1, a warning from tslint appears: [ts] Cannot ...

The error message "better-sqlite3 TypeError: o.default is not a constructor" indicates that

As part of my vscode extension development in typescript, webpack, and better-sqlite3, I am attempting to create a database within the C:\Users\userName\AppData\Roaming\Code\User\globalStorage\ folder. However, when ...

What is the method for displaying script commands within package.json files?

With a multitude of repositories, each one unique in its setup, I find myself constantly referencing the package.json file to double-check the scripts. "scripts": { "start": "npm run dev" "build:dev": "N ...

Obtaining undefined values for req and resolvedUrl in GetServerSideProps function

In my project, I am currently using next.js version ""next": "^12.1.4"" and node version ""@types/node": "^14.14.6". I have created a function called getServerSideProps with parameters req and resolvedUrl. When the ...

Looking to incorporate Functional Components in React using the package "@types/react" version "^18.0.17"? Learn how here!

With the removal of the children prop from React.FC type, what is the new approach for typing components? ...

Utilize the ng.IFilterService interface within a TypeScript project

I am facing an issue with a .ts file that contains the following code: module App.Filters { export class SplitRangeFilter implements ng.IFilterService { static $inject = ['$filter']; public static factory(): Function { ...

Apply a spread of nested elements onto another spread

I am working with an array containing last names of Persons and need to populate new entries. However, I only have the last names and not the full Person objects. How can I address this issue? type Person = { name: string, lastName: string, age: ...

Ways to modify the access control to permit origin on a specific API URL in React

https://i.stack.imgur.com/tqQwO.png Is there a way to modify the access control allow origin for a URL API? I keep encountering error 500 whenever I try to load the page. After logging in, I included this code snippet: const options = { header ...