cypress icon indicating copy to clipboard operation
cypress copied to clipboard

Angular Component Testing cannot find type definition files

Open cg-roling opened this issue 2 years ago • 2 comments

Current behavior

When running Cypress component files, type definition files added to compilerOptions.types in tsconfig.app.json are not found.

If I add the "node" type definitions, I get the following output from npx cypress run --component:

asset cypress_support_component_ts.js 2.38 MiB {cypress_support_component_ts} [cached] (name: Volumes-Files-git-cy-comp-cypress-support-component-ts) 1 related asset
asset default-node_modules_angular_core_fesm2020_core_mjs.js 1.2 MiB {default-node_modules_angular_core_fesm2020_core_mjs} [cached] (name: Volumes-Files-git-cy-comp-cypress-support-component-ts) (i
d hint: default) 1 related asset
asset polyfills.js 318 KiB {polyfills} [cached] (name: polyfills) 1 related asset
asset cypress-entry.js 213 KiB {cypress-entry} [cached] (name: cypress-entry) 1 related asset
asset styles.js 209 KiB {styles} [cached] (name: styles) 1 related asset
asset runtime.js 12.6 KiB {runtime} [cached] (name: runtime) 1 related asset
asset spec-0.js 2.11 KiB {spec-0} [cached] (name: spec-0) 1 related asset
asset favicon.ico 948 bytes [cached] [from: src/favicon.ico] [copied]
asset styles.css 736 bytes {styles} [cached] (name: styles) 1 related asset
asset index.html 605 bytes [cached]
Entrypoint polyfills = runtime.js polyfills.js 2 auxiliary assets
Entrypoint styles = runtime.js styles.css styles.js 3 auxiliary assets
Entrypoint cypress-entry = runtime.js cypress-entry.js 2 auxiliary assets
chunk {cypress-entry} (runtime: runtime) cypress-entry.js (cypress-entry) 196 KiB [initial] [rendered]
chunk {cypress_support_component_ts} (runtime: runtime) cypress_support_component_ts.js (Volumes-Files-git-cy-comp-cypress-support-component-ts) 2.32 MiB [rendered]
chunk {default-node_modules_angular_core_fesm2020_core_mjs} (runtime: runtime) default-node_modules_angular_core_fesm2020_core_mjs.js (Volumes-Files-git-cy-comp-cypress-support-component-ts) (id hi
nt: default) 1.14 MiB [rendered] split chunk (cache group: default)
chunk {polyfills} (runtime: runtime) polyfills.js (polyfills) 303 KiB [initial] [rendered]
chunk {runtime} (runtime: runtime) runtime.js (runtime) 7.59 KiB [entry] [rendered]
chunk {spec-0} (runtime: runtime) spec-0.js (spec-0) 871 bytes [rendered]
chunk {styles} (runtime: runtime) styles.css, styles.js (styles) 195 KiB (javascript) 80 bytes (css/mini-extract) [initial] [rendered]

ERROR in error TS2688: Cannot find type definition file for 'node'.
  The file is in the program because:
    Entry point of type library 'node' specified in compilerOptions

Desired behavior

tsconfig "types" should be found for component tests

Test code to reproduce

Reproduction is available here: https://github.com/cg-roling/cypress-component-types-repro

I followed the Getting Started Guide and created a new Angular project, along with a component and spec.

npx cypress run --component works perfectly at this point.

Then I edited tsconfig.app.json and added "node" to the types config option. I used "node" because it's already installed, any type definition causes the same error.

npx cypress run --component now shows:

ERROR in error TS2688: Cannot find type definition file for 'node'.
  The file is in the program because:
    Entry point of type library 'node' specified in compilerOptions

This is my edited tsconfig.app.json:

/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "./out-tsc/app",
    "types": ["node"]
  },
  "files": ["src/main.ts", "src/polyfills.ts"],
  "include": ["src/**/*.d.ts"]
}

Cypress Version

10.8.0

Node version

v16.14.2

Operating System

macOS 13 Beta

Debug Logs

Logs are too long to include here, I can include relevant parts if necessary.

Other

Type definitions in local .d.ts files appear to be missing as well.

cg-roling avatar Sep 15 '22 23:09 cg-roling

@cg-roling thanks for opening the issue, I was able to reproduce the problem with your provided repo, we are going to have to change how we generate/manage our handling of the tsconfigs in order to get a fix for this problem.

In the meantime, you should be able to workaround this issue by using the /// <reference types="x" /> in your cypress/support/component.ts file. For example, if you wanted to include the types for "node" you would add:

/// <reference types="node" />

and that will add the types to the compilation. I'm going to follow up with my ideas on how to get a proper fix for this problem.

Edit:

Following up on this, this issue points out two issues that we have with our current Angular implementation for handling types/tsconfig.

  1. The first problem is that types: [...] in the user's tsconfig.app.json (or the tsconfig specified in devServer.options.projectConfig) aren't being included. From my investigation, this is due to where we generate the tsconfig for the project which is an os-specific temporary directory. By default, the typeRoots property is configured to recursively search for node_modules/@types relative to the location of the tsconfig. Since this "temporary" tsconfig is not generated inside the project, it won't find the project's node_modules/@types. Changing the temporary tsconfig to be generated inside the project would alleviate this problem and we could utilize a commonly gitignored folder ("dist", "out-tsc", "tmp", even "node_modules"). We could also set typeRoots to point to the project, but would have to verify if the recursive search works to handle monorepos.
  2. The second problem is that the tsconfig we generate overrides the include property that the extended tsconfig might have. For example if the user's tsconfig.app.json has "include": ["src/**/*.d.ts"], their declaration files wouldn't be included. An option here would be to concat the existing include into the array that we generate in our tsconfig to preserve this.

For context, when building the Angular application we don't use the given tsconfig property found in the build options but rather extend from it by generating another tsconfig. These issues are a result of this decision where the location of this generated tsconfig affects the type resolution and the merging/overriding of the properties changes the properties that the user might expect to not be changed.

Another option to remove a lot of this complexity would be to scaffold a tsconfig.cypress.json (source-controlled) that would be used rather than generating one on demand. That way, the user could modify this file to add types and change the compilation options themselves if need be. This would make it very transparent as to what files and options are being used to compile their application rather than obfuscate it from the user.

ZachJW34 avatar Sep 19 '22 15:09 ZachJW34

Awesome, thanks for the workaround, that should get us going for sure!

In terms of a fix, from my perspective anyway, a "real" tsconfig.cypress.json rather than a generated one certainly seems easier to debug.

cg-roling avatar Sep 19 '22 18:09 cg-roling

Hey team! Please add your planning poker estimate with Zenhub @amehta265 @astone123 @lmiller1990 @mike-plummer @warrensplayer @ZachJW34

rockindahizzy avatar Dec 19 '22 17:12 rockindahizzy

Another option to remove a lot of this complexity would be to scaffold a tsconfig.cypress.json (source-controlled) that would be used rather than generating one on demand. That way, the user could modify this file to add types and change the compilation options themselves if need be. This would make it very transparent as to what files and options are being used to compile their application rather than obfuscate it from the user.

Is this the fix we are going with? This seems like most reliable and explicit fix. It's also similar to what we do for End to End testing. We will need to ensure it's compatible with that, too. Can they share the same cypress/tsconfig.json?

In that case, we would add this during the scaffold phase?

This won't fix existing projects - we might need to document this under the "Angular" section in our docs.

Also, projects like Nx will need updating to ensure they also scaffold this file. We probably don't need to update those, but we could file and issue informing them of the need for a tsconfig.cypress.json for an improved out of the box experience.

There's a few open questions here. I've considered that in my ticket estimate.

lmiller1990 avatar Dec 20 '22 01:12 lmiller1990

I think scaffolding an explicit tsconfig is the way to go. This should be a non-breaking change, so we should keep the functionality we have and extend it with the ability to have an explicit one. Communicating with the Nx team will be a good idea.

ZachJW34 avatar Dec 20 '22 15:12 ZachJW34

Hey team! Any update on this?

petergaal91 avatar Jun 20 '23 18:06 petergaal91

Is this happening out of the box? I haven't seen this error in a while, did you find this in a newly created project or and existing, more complex one?

What version of Cypress / Angular / Nx (if using) are you on?

lmiller1990 avatar Jun 20 '23 22:06 lmiller1990

I created a reproduction repo to my issue: https://github.com/petergaal91/angular-cypress It's a monorepo with two angular applications: admin and client.

Both uses cypress component tests but in a different folder structure:

  • admin: uses the cypress folder
  • client: uses the tests/component folder

Both loads a static.html file with raw-loader. For this we need to create a shims.d.ts file in the src folder, where we can define a *.html module for that import, what I did in both folder. And here comes the error with cypress:

ERROR in src/app/app.component.ts:2:27 - error TS2307: Cannot find module 'raw-loader!./static.html' or its corresponding type declarations.

2 import staticContent from 'raw-loader!./static.html';

I can't load shims.d.ts file when cypress compiles the code. I added tsconfig.json files into the cypress folders but none of them worked for me.

This is the reason why I asked what's up with this, because I need to configure tsconfig related things (load d.ts file in this case)

petergaal91 avatar Jun 21 '23 09:06 petergaal91

Thank for for this. @jordanpowell88 will take a look in the next day or two -- if not, I can 👀 early next week.

Can you please ping me if I miss this by mid next week? Many issues to juggle right now 🤯

lmiller1990 avatar Jun 21 '23 21:06 lmiller1990

@lmiller1990 or @jordanpowell88 Could you check my repo again please? I have the same issue with [email protected], so my error not resolved. https://github.com/petergaal91/angular-cypress

petergaal91 avatar Sep 04 '23 12:09 petergaal91