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

How can I receive the response from a GET request using React Query? I am currently only able to get the response

I have created a search component where I input a name in the request, receive a response, and display it immediately. However, after the first input submit, I get undefined in response. Only after the second submit do I get the desired response. The tec ...

After executing a query to a PostgreSQL database, I encountered an error preventing me from using res.send(). The error message stated: "Cannot set headers after they are sent to the client."

It may sound strange, but it's a true story. I was busy building an API on node.js when I encountered a peculiar error. As soon as the first res.status().send() was triggered during query processing, VS Code threw a "Cannot set headers after they are ...

What causes the function endpoint to become unreachable when a throw is used?

One practical application of the never type in typescript occurs when a function has an endpoint that is never reached. However, I'm unsure why the throw statement specifically results in this unreachable endpoint. function error(message: string): ne ...

The CloudWatch logs for a JavaScript Lambda function reveal that its handler is failing to load functions that are defined in external

Hello there, AWS Lambda (JavaScript/TypeScript) is here. I have developed a Lambda handler that performs certain functions when invoked. Let me walk you through the details: import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda' ...

Issue with routing in Angular 6 is caused by the "#" character

I am currently working on an Angular 6 project. In my app.routes, I have set it up like this. However, I am facing an issue where I can only access the route using localhost:4200/#/Student instead of localhost:4200/Student. Can you help me identify where t ...

Expanding a given type using Typescript

My goal is to construct a custom table using Angular, where I aim to define a TableItem type that enforces the presence of a label property for every item added to the table. For instance, consider this example: <app-my-table [items]="items&qu ...

Exporting third party definitions from a TypeScript npm module for reuse in other projects

Our custom npm logging module, which is built using TypeScript and relies on the pino library, encounters errors when being imported into an application: Error: node_modules/@scope/logging/lib/index.d.ts(1,23): error TS2688: 'pino' type definiti ...

Looking to personalize the MUI - datatable's toolbar and place the pagination at the top?

I successfully managed to hide the toolbar icon, but I am struggling with positioning pagination from bottom to top. Additionally, I am attempting to add two buttons (reset and apply) in the view-Column toolbar without any success in customizing the class. ...

Achieving TypeScript strictNullChecks compatibility with vanilla JavaScript functions that return undefined

In JavaScript, when an error occurs idiomatic JS code returns undefined. I converted this code to TypeScript and encountered a problem. function multiply(foo: number | undefined){ if (typeof foo !== "number"){ return; }; return 5 * foo; } ...

Array that accepts the type of the first element as its generic parameter

There was a type challenge The task was to create a generic function called First that takes an array T and returns the type of its first element. type arr1 = ["a", "b", "c"]; type arr2 = [3, 2, 1]; type head1 = First<arr1>; // expected: 'a& ...

Validating mixed types and generics within an array using Typescript's type checking

I am currently working with a setup that involves defining interfaces for animals and their noises, along with classes for specific animals like dogs and cats. I am also storing these animals in an array named pets. interface Animal<T> { name: stri ...

Error occurred when sending form data while uploading a file

Upon trying to upload a file using the formData.append(key, value);, an error message is displayed in the value section: The argument of type 'unknown' cannot be assigned to a parameter of type 'string | Blob'. Type '{}' is ...

What could be causing the service method in the controller not to be called by Node JS?

In my current Node JS project, the folder structure of my app is as follows: src │ index.js # Main entry point for application └───config # Contains application environment variables and secrets └───controllers # Hou ...

Can a generic type be utilized to instantiate an object?

In my code, I have a class named Entity as shown below: class Entity { constructor(readonly someValue: string) {} someFunction() {} } Now, I am trying to create a class that will handle these entities and be able to create instances of them. In or ...

Instructions on how to dynamically show specific text within a reusable component by utilizing React and JavaScript

My goal is to conditionally display text in a reusable component using React and JavaScript. I have a Bar component that I use in multiple other components. In one particular ParentComponent, the requirement is to show limit/total instead of percentage va ...

Angular 6: Dealing with Type Errors in the HttpClient Request

I am encountering issues with my services. I am attempting to retrieve a list of media files (generated by NodeJS, which generates a JSON file containing all media items). Although I can successfully fetch the data, I am facing an error stating "Property & ...

Retrieve the accurate file name and line number from the stack: Error object in a JavaScript React Typescript application

My React application with TypeScript is currently running on localhost. I have implemented a try...catch block in my code to handle errors thrown by child components. I am trying to display the source of the error (such as file name, method, line number, ...

What is the correct way to use Observables in Angular to send an array from a Parent component to a Child

Initially, the task was to send JSON data from the parent component to the child component. However, loading the data through an HTTP request in the ngOnInit event posed a challenge as the data wasn't being transmitted to the child component. Here is ...

Using Lerna with Docker for Next.js and GraphQL applications

Currently, I am working with lerna and everything runs smoothly locally. However, when I attempt to build the image and operate it through Docker, it does not function as expected. FROM node:16-alpine3.11 ENV NODE_ENV=production COPY . /app WORKDIR /app R ...

The JSX component cannot use 'Router' as a valid element

Error Message The error message states that 'Router' cannot be used as a JSX component because its return type 'void' is not a valid JSX element. TS2786 import App from './App'; 5 | > 6 | ReactDOM.render(<Router ...