Cypress在Jest断言中引起类型错误。

110

我之前一直在使用react-testing-library以及@testing-library/jest-dom/extend-expect。昨天我安装了Cypress,现在所有的jest匹配器都出现Typescript错误:

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

似乎是从错误的断言库获取了expect的类型?此外,expect(...).to.equal(...)也无法工作。

我尝试安装了@types/jest,看起来yarn已经成功了,但它没有列在我的package.jsondevDependencies中。

以下是我的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"
  ]
}

我还要提到,我的所有Cypress测试中的cy调用都会收到来自ESLint的cy未定义错误。


自从Cypress v10以来,错误的主要原因./cypress.config.ts。建议首先尝试Marcus Fonseca的答案 - Michael Freidgeim
19个回答

78

我昨天遇到了这个问题。似乎你说得对,cypress 和 jest 都声明了 expect 的类型。在这种情况下,似乎选择了 cypress 声明的类型。这里有一个来自 cypress 存储库的问题:

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

那里提到的解决方案对我有用。您需要在tsconfig.json中排除jest spec文件,然后声明一个tsconfig.spec.json,在其中明确包含它们。

tsconfig.json:

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

tsconfig.spec.json:

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

有了这个设置,我的(angular 8)应用程序编译良好,我可以无问题地运行jest测试。以下是在问题中提到的另一个类似修复的示例:

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

注意 2023 年 3 月 9 日:自从 Cypress v10 版本以来,错误的 主要原因./cypress.config.ts。 建议先尝试 Marcus Fonseca 的答案


你是指Cypress的.spec文件吗? - foakesm
2
@foakesm 如果上面的文本不太清楚,那么基础的 tsconfig.json 将会排除 jest.spec 文件,然后 tsconfig.spec.json(jest 使用的)将会包含它们。为了让这个工作正常,我们假设你的 Cypress 测试不是在名为 *.spec.ts 的文件中。这回答了你的问题吗? - Johan Persson
这个方法同样适用于在Angular工作区中使用Cypress + Jasmine时遇到相同问题的情况。谢谢! - Jaime Still
这个问题涉及到Angular中的Karma/Jasmine。我的解决方案是关闭所有*.spec.ts文件并进行排除/包含操作。似乎需要对Angular文件进行“重新启动”才能正确获取更改。 - Steffo Dimfelt
这种方法在VSCODE提示方面存在缺点。VSCODE使用TypeScript服务器,它无法使用两个tsconfig文件。在这种情况下更好的方法是使用import { expect } from '@jest/globals'; - georgelviv
对我来说没问题!我正在寻找在一个目录中同时使用Cypress组件测试和Jasmine单元测试的解决方案。 - Verri

66

有人在 GitHub问题“New Cypress 10全局TypeScript类型与Jest expect冲突”中遇到这个问题,但已经有了解决方法

通过在您的tsconfig.json中排除./cypress.config.ts来解决此问题

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

来自Cypress开发者:

我们在v10中并没有对全局变量进行太多更改。对于我重现的所有情况,通过将./cypress.config.ts添加到tsconfig.exclude属性中解决了问题。由于cypress.config.ts已包含在类型检查中,它正在加载cypress类型,这会污染您的jest测试。


1
谢谢,这也对我们的单体库项目有所帮助。 - darmis
2
这个!而且我还必须在我的eslint配置中“排除”所有的cypress测试文件,因为这些文件也包含“cypress”,会污染jest typings。 - Krisztián Balla
谢谢,这也对我们的React项目有所帮助。 - ZR87
1
我得到了“找不到名称'cy'”。 - Alexander
现在我在所有的Cypress测试中也遇到了“找不到名称'cy'”的问题。 - undefined
显示剩余2条评论

66

我已经关注了官方的Cypress代码库。感谢提供链接。 - Rick
这是我唯一有效的方法,但最好能够得到适当的解决 :/. - iMe
1
在用尽了所有的咒骂词汇后,我终于在 Cypress 官方仓库中引用了这个答案中提到的 cypress-and-jest-typescript-example 的链接,该链接成功运行在我的 Angular 15 + Cypress 12 项目中。唯一的区别就是在 tsconfig.json 文件中,我将 “exclude” 更改为 [“src/*.spec.ts”]。 - Mike Woinoski
同样的,所有的配置把戏都没有起作用,因为它直接从node_modules导入了cypress,即使没有带有测试规范的cypress文件夹。但这是疯狂的,不是一个真正的解决方案。 - sasklacz

25

终于我找到了解决方案!只需将"cypress"添加到您的主tsconfig.jsonexclude属性中:

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

您还应为Cypress测试添加另一个tsconfig.json文件。 您可以创建一个名为cypress的文件夹并在其中添加tsconfig.json文件。 以下是我的Cypress tsconfig.json

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


使用 exclude:[cypress] 是个好建议,对我很有帮助。 - Caleb Waldner
这应该是被接受的答案。如果您也有cypress.config.ts,请将其排除在外。 - user3932000

17

这对我的tsconfig.json有效。

我不得不添加

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

完整代码在此处

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

这对我来说也是关键。在根目录的 tsconfig.json 中添加 src/** 解决了问题,之前查看了示例仓库中的其他设置:https://github.com/cypress-io/cypress-and-jest-typescript-example。 - natterstefan

13

有几种情况会导致这个问题。在我的情况下,通过将"./cypress.config.ts"添加到"tsconfig.exclude"属性中来解决了这个问题。由于"cypress.config.ts"被包含在类型检查中,它会加载污染你的jest测试的cypress类型。我相信如果你正在使用typscript进行cypress配置,这将对你有所帮助。


想知道是否有一种方法可以保持其包含但不会引起那个问题。 - Dmitry
2
好的,看起来这是自Cypress v10以来唯一可能的解决方案。他们建议排除 cypress.config.ts 并将其包含在 <root>/cypress/tsconfig.ts 中(如果您当然正在为 Cypress 使用分离的 tsconfig)。 https://github.com/cypress-io/cypress/issues/22059 - Dmitry

11

让它消失有三个步骤。

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

到达最高级别配置。就是这样。

一些额外的注意事项:

  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.


添加 "exclude": [] 也解决了我的问题,非常好的建议。 - Dan Barclay

5
解决这个问题最简单的方法是在tsconfig.json中添加这一行:
  "include": [
    "src/**/*.ts"
  ],

我附上了我的tsconfig文件以便更好地理解。您可以在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
  }
}

谢谢!在我的Ionic应用程序中,使用jasmine/cypress工作正常。我需要关闭Visual Studio Code并重新打开它。 - Greg B.

4
我遇到了同样的问题,在尝试了上面的选项后,组合使用两个解决方案可行。 将以下内容添加到测试文件中:
import { expect } from '@jest/globals';.

并将此添加到tsconfig.json中(包含以防止jest @types错误)

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

它运行良好,但我不必更新tsconfig.sjon。 - Gnopor

2
在我的情况下,它只有一个帮助:将 "types": ["jest"] 添加到 "compilerOptions" 中。
{
  "compilerOptions": {
    ...
    "types": ["jest"],
   ...
  },     
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接