jest-preset-angular icon indicating copy to clipboard operation
jest-preset-angular copied to clipboard

FAQ for issues and solutions which can appear

Open thekip opened this issue 6 years ago • 43 comments

I think this not a secret that "Angular + Jest" isn't a popular solution. So it's quite hard to find any information in the internet if you face any problems. I have a quite big project, (about 30mb in mono-repo) and while migrating to Jest I faced lot of issues which not described anywhere in the internet.

So my proposal, we can create a Wiki page on this github and start gather issues with solutions. To make use of Jest + Angular delightful and painless.

I can start from some:

  1. Q: ReferenceError: CSS is not defined when testing components which used Material Design lib.

    A: Material Design library has a special check whether it run in browser environment or not. This check fails in jsdom, environment, because it's emulate browser, but not for all cases.

add this to setup-jest.ts

Object.defineProperty(window, 'CSS', {value: () => ({})});
  1. Q: Could not find Angular Material core theme.. or Could not find HammerJS when testing components which used Material Design lib.

    A: There few possible solutions, but most bulletproof:

add this to setup-jest.ts

const WARN_SUPPRESSING_PATTERNS = [
/Could not find Angular Material core theme/,
/Could not find HammerJS/,
];

const warn = console.warn;

Object.defineProperty(console, 'warn', {
 value: (...params: string[]) => {
   if (!WARN_SUPPRESSING_PATTERNS.some((pattern) => pattern.test(params[0]))) {
     warn(...params);
   }
 }
});

3: Q: When run with coverage get this errors

No file coverage available for: c:\projects\meteoguard\src\app\tasks\shared\index.ts at CoverageMap.fileCoverageFor (node_modules/istanbul-lib-coverage/lib/coverage-map.js:96:15)

A: this errors appears only for index.ts files which has only import/export statements,actually I don't know why it happens (may be typescript compilation output is empty for this files), but as a workaround you can just add this index.ts files to coverage ignore pattern. Even more, this index.ts files don't have any value for coverage

package.json

 "jest": {
    "coveragePathIgnorePatterns": [
      "/node_modules/",
      "index.ts"
    ],
  },
  1. Q: "Syntax Error: Invalid or unexpected token" with absolutely unhelpful stack trace.

A: Probably there is a require of file type which is not supported by Jest itself. For instance "png". Follow jest documentation: https://facebook.github.io/jest/docs/en/webpack.html#content

thekip avatar Oct 09 '17 07:10 thekip

Awesome you share this, thank you! There is Troubleshooting section on the Readme, where we can add extra information you provided. If you have any ideas on how to make it more discoverable, please post it here.

thymikee avatar Oct 09 '17 08:10 thymikee

Probably we can create a Wiki for this project, and store all information there. I think put it into readme not a good idea.

The main thing, that this wiki page should be well prepared for google, that other developers may just copy/paste error message and find a solution.

thekip avatar Oct 09 '17 09:10 thekip

in additional to first post

  1. Using '"target": "es6"' in jest setup is not currently supported by Angular JIT compiler.

TypeError: Cannot convert undefined or null to object at Function.getPrototypeOf ()

at getParentCtor (node_modules/@angular/core/bundles/core.umd.js:1825:47)

Issue for tracking https://github.com/angular/angular/issues/15127

thekip avatar Oct 09 '17 13:10 thekip

Could not find Angular Material core theme

Full error message:

console.warn node_modules/@angular/material/bundles/material.umd.js:191
      Could not find Angular Material core theme. Most Material components may not work as expected. For more info refer to the theming guide: https://material.angular.io/guide/theming

Solution

A possible fix is to trick angular material into thinking that the core theme is loaded by adding a selector to the JSDOM page in your setupJest.ts file

declare var global: any;
const style = global.document.createElement('style');
style.innerHTML = `
  .mat-theme-loaded-marker {
    display: none;
  }
`;
global.document.head.appendChild(style);

This is an ugly workaround and will break if future versions of angular material do theme detection differently.

damoonrashidi avatar Oct 20 '17 08:10 damoonrashidi

Not an Angular developer, but rather node + TS. Still @thekip saved me a lot of headache with his 3. tip! 😍 Just here to say thank you!

sebald avatar Nov 10 '17 10:11 sebald

Thanks for warm words. Add couple thinks which figured out after updating to Angular 5 and latest material.

Q: While testing components which used Material Design lib, you receive an error

TypeError: Cannot read property 'bind' of undefined at new MediaMatcher (node_modules/@angular/cdk/bundles/cdk/layout.es5.js:36:30)

A: Material Design library uses matchMedia browser api, wich is not presented in JsDom we need mock it.

add this to setup-jest.ts

Object.defineProperty(window, 'matchMedia', { value: () => (
 {
   matches : false,
   addListener: () => { },
   removeListener: () => { },
 }
) });

Q: While testing components with animation in Angular 5 you receive an error:

The animation trigger "X" has failed to build due to the following errors: The provided animation property "transform" is not a supported CSS property for animations

Object.defineProperty(document.body.style, 'transform', {
  value: () =>
    ({
      enumerable: true,
      configurable: true,
    }),
});

thekip avatar Nov 10 '17 15:11 thekip

The solution above no longer works (at least not for me)

bhanna1693 avatar Aug 17 '21 12:08 bhanna1693

in you test you can set in providers this:

 {
    provide: MATERIAL_SANITY_CHECKS, 
    useValue: false
 }

bdimir avatar Aug 25 '21 08:08 bdimir

Hi all!

I'm far from being a build/test expert, so I run into an issue with testing code using a WebWorker created with the ng generate web-worker CLI tool.

Running the test gives me

src/app/mydata.service.ts:147:49 - error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'es2020', 'esnext', or 'system'.

            new URL("./mydata.service.worker", import.meta.url)

I tried my best to make my way thru the docs - without success. Can somebody give me a hand?

joergplewe avatar Sep 07 '21 16:09 joergplewe

import meta is an ESM feature which doesn’t work with default NodeJs commonjs mode. You need to run Jest in ESM mode.

you can check our documentation how to use ESM mode with Jest.

ahnpnl avatar Sep 07 '21 16:09 ahnpnl

Wow ... that was quick. I tried the following w/o success. Something more to do?

// require('jest-preset-angular/ngcc-jest-processor');

module.exports = {
  // preset: "jest-preset-angular",
  preset: "jest-preset-angular/presets/defaults-esm",
  setupFilesAfterEnv: ["<rootDir>/jest.setup.ts"],
  setupFiles: ["jest-canvas-mock", "jest-webgl-canvas-mock"],
  moduleNameMapper: {
    "~/(.*)": "<rootDir>/src/$1",
  },
};

joergplewe avatar Sep 07 '21 16:09 joergplewe

Only make sure you run Jest with node esm flag, run ngcc (or use our ngcc script), set tsconfig to use module ESNext. You can also check our examples folder where we have ESM setup.

ahnpnl avatar Sep 07 '21 17:09 ahnpnl

Thank you so far ... I cannot find a difference. Using --experimental-vm-modules (which seems to be essential?) fails at a different place. I will try to create a WebWorker on an example project and see wether it works.

joergplewe avatar Sep 07 '21 17:09 joergplewe

Having trouble using ngcc-jest-processor.

If i run ngcc after install , all jest esm tests are working fine, but when only using ngcc-jest-processor import, most tests fail since [email protected]

Syntax error reading regular expression.
  at @:2:108
  at ../../@:2:108
  at regularExpression (../../node_modules/cjs-module-lexer/lexer.js:1289:9)
  at parseSource (../../node_modules/cjs-module-lexer/lexer.js:228:13)
  at parseCJS (../../node_modules/cjs-module-lexer/lexer.js:43:5)

SyntaxError: The requested module '@angular/core' does not provide an export named 'Pipe'
  at Runtime.linkAndEvaluateModule (../../node_modules/jest-runtime/build/index.js:759:5)
  
SyntaxError: The requested module 'rxjs/operators' does not provide an export named 'map'
  at Runtime.linkAndEvaluateModule (../../node_modules/jest-runtime/build/index.js:759:5)

viceice avatar Sep 20 '21 15:09 viceice

That sounds strange because under the hood that util script invokes the same way as ngcc does. It could be Jest cache issue that you see different behaviors. I would expect the behavior is the same.

ahnpnl avatar Sep 20 '21 16:09 ahnpnl

yes, cleared local jest cache seems to fix my local tests, but having issues on ci. it's running inside ephemeral docker containers.

Only the workspace is held but there is a git clean before any other commands. also currently no yarn cache involved. very strange 🤔

viceice avatar Sep 20 '21 16:09 viceice

The script is optional to use anyways :) Its purpose was to remind others not to “forget”to run ngcc before running Jest.

ahnpnl avatar Sep 20 '21 16:09 ahnpnl

it's getting more strange. running it on ci fails with same error. when i then run the same docker image and jest command, it succeeds as it does locally.

BTW: I'm using a nrwl nx workspace

viceice avatar Sep 20 '21 19:09 viceice

I think nx has a cache on test which somehow takes over or does something with Jest cache.

ahnpnl avatar Sep 20 '21 19:09 ahnpnl

i think it's not an nx issue, as i'm running jest directly.

I got it back working. I exclude the tslib moduleNameMapper and set importHelpers=false

viceice avatar Sep 21 '21 06:09 viceice

Seem like tslib has changed something which makes the moduleNameMapper in the preset not correct anymore. Thanks for the information 🙏

ahnpnl avatar Sep 21 '21 06:09 ahnpnl

This is the tslib diff from v2.3.0 to v2.3.1. I'm not sure how this small change can cause those big issues 🤔

https://app.renovatebot.com/package-diff?name=tslib&from=2.3.0&to=2.3.1

viceice avatar Sep 21 '21 07:09 viceice

I just corrected ESM tests in examples of this repo but couldn’t see the issue like yours, see https://github.com/thymikee/jest-preset-angular/actions/runs/1257005889 Our examples don’t have nx

ahnpnl avatar Sep 21 '21 10:09 ahnpnl

in you test you can set in providers this:

 {
    provide: MATERIAL_SANITY_CHECKS, 
    useValue: false
 }

Has anyone found a way to enable this for a whole Nx monorepo? Visiting all tests and testbeds to add this provider when an Angular Material part is being used feels a little, strange and time consuming.

Bjeaurn avatar Sep 21 '21 11:09 Bjeaurn

I just corrected ESM tests in examples of this repo but couldn’t see the issue like yours, see https://github.com/thymikee/jest-preset-angular/actions/runs/1257005889 Our examples don’t have nx

Your tests use [email protected] and i wrote above, it happened when I upgrade to [email protected]

https://github.com/thymikee/jest-preset-angular/blob/ce41947b6d981eb1a1a1371bd17884bb705e9c23/examples/example-app-v12-monorepo/yarn.lock#L8441-L8444

the example-app-v12-monorepo sample is somehow comparable to the nx based configs

viceice avatar Sep 21 '21 11:09 viceice

I upgraded tslib to 2.3.1 https://github.com/thymikee/jest-preset-angular/pull/1025 but still couldn't see the same issue you had.

ahnpnl avatar Sep 21 '21 12:09 ahnpnl

in you test you can set in providers this:

 {
    provide: MATERIAL_SANITY_CHECKS, 
    useValue: false
 }

Has anyone found a way to enable this for a whole Nx monorepo? Visiting all tests and testbeds to add this provider when an Angular Material part is being used feels a little, strange and time consuming.

I would like to know how to handle this globally in an Nx repo, as well. Doing this for every component might be a challenge.

nickroberts avatar Sep 22 '21 16:09 nickroberts

in you test you can set in providers this:

 {
    provide: MATERIAL_SANITY_CHECKS, 
    useValue: false
 }

Has anyone found a way to enable this for a whole Nx monorepo? Visiting all tests and testbeds to add this provider when an Angular Material part is being used feels a little, strange and time consuming.

Just an idea. You can create a MaterialTestingModule that would import/export all your commonly used Material modules as well as this provider. Then use this in your tests instead of manually importing a bunch of material modules.

const modules: Type<unknown>[] = [
    MatButtonModule,
    MatDialogModule,
    ...
];

@NgModule({
    imports: [
        modules,
    ],
    exports: [
        modules,
    ],
    providers: [
        {
            provide: MATERIAL_SANITY_CHECKS,
            useValue: false
        }
    ]
})
export class SharedUtilTestingMaterialModule { }

anatolie-darii avatar Sep 24 '21 06:09 anatolie-darii

Hello everyone, maybe someone knows the reasons why this warning "Could not find Angular Material core theme.." may appear at all? In my app it was not there before, but as soon as I updated jest to 27.2 and jest-preset-angular to 10.0.1, it appeared ( all tests pass successfully and I dont have problems with Angular Material core theme in my angular-cli app in general ).

Thank you in advance

MrTwisterAnastasia avatar Oct 05 '21 06:10 MrTwisterAnastasia

Hello everyone, maybe someone knows the reasons why this warning "Could not find Angular Material core theme.." may appear at all? In my app it was not there before, but as soon as I updated jest to 27.2 and jest-preset-angular to 10.0.1, it appeared ( all tests pass successfully and I dont have problems with Angular Material core theme in my angular-cli app in general ).

Thank you in advance

The warning comes from Angular Material itself. You can bypass it by

providers: [{provide: MATERIAL_SANITY_CHECKS, useValue: false}]

see https://github.com/angular/components/issues/4125#issuecomment-347139081

ahnpnl avatar Oct 05 '21 07:10 ahnpnl

Hello all,

I'm facing an issue with Jest and PrimeNG components... All Prime components don't find their css file when I run Jest. Ex : image

Maybe someone already faced this problem ?

Thank you !

"@angular/core": "~12.2.10" "jest-preset-angular": "^10.0.1" "jest": "^27.3.0"

Adrii77 avatar Oct 18 '21 14:10 Adrii77

Hello all,

I'm facing an issue with Jest and PrimeNG components... All Prime components don't find their css file when I run Jest. Ex : image

Maybe someone already faced this problem ?

Thank you !

"@angular/core": "~12.2.10" "jest-preset-angular": "^10.0.1" "jest": "^27.3.0"

@Adrii77

In our case this problem occured because primeng was not compiled in a format suitable for tests. It was only precompiled as ESM2015. We fixed this issue by running the following postinstall command. It compiles primeng into UMD format. We added the command to package.json

{
  "scripts": {
           //...
           "postinstall": "ngcc --properties es2015 browser module main"
           //...
  }
}

marcuskrahl avatar Oct 25 '21 07:10 marcuskrahl

Here's one that I've encountered recently. Previously, our tsconfig had:

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

We did this to minimize the surface area that jest processes (since the *.spec files are the entrypoints). This worked fine before migrating to ES modules.

After migrating to ES modules, we started seeing some difficult-to-fix errors that seemed to indicate the interface imports are occasionally missing. For example:

 FAIL   Angular Tests  libs/logging/src/logging.service.spec.ts
  ● Test suite failed to run

    SyntaxError: The requested module '../model/logging-config' does not provide an export named 'LoggingConfig'

      at Runtime.linkAndEvaluateModule (node_modules/jest-runtime/build/index.js:779:5)

The file has the exported interface LoggingConfig, in spite of the error message. It is expected that typescript removes the export from the js file, and removes the import from the importing js file - this worked fine previously. In some cases the missing export was reported for imports from *.spec.ts files, and in other cases the missing export was reported for imports from files linked to the *.spec.ts files.

The "fix" turned out to be updating tsconfig.spec.json to:

  "include": [
    "src/**/*.ts",
    <any other paths to pull in your test files>
  ],

This seems to slow the tests down, but they work. There's a case to be made that this should be filed as a bug instead of an issue + solution, but as far as I can tell from looking at the code this is in the ts compiler, not jest-preset-angular.

I have not been able to create a simple repro for this - it definitely doesn't happen for all interface imports. My theory is that it happens when there are multiple files importing the interface, and it may be a race condition related to ordering of file transformation.

johncrim avatar Feb 02 '22 06:02 johncrim

Here's another one that you'll probably run into when migrating to ES modules. When migrating to ESM, you'll need to add @jest/globals imports to all your test files that use jest and expect globals. This will break any expect extensions you are using (eg @ngneat/spectator, jest-extended), with errors like:

FAIL  src/expect-extension-jest-globals.spec.ts
  ● Test suite failed to run

    src/expect-extension-jest-globals.spec.ts:6:18 - error TS2339: Property 'toIncludeSameMembers' does not exist on type 'Matchers<void, number[]>'.

The cause it that the type that @jest/globals: expect() returns is different from the type non ESM expect() returns, which breaks all the type merging for extensions. I've filed the bug with jest, and documented a workaround.

johncrim avatar Feb 02 '22 17:02 johncrim

I got this during latest update o the angular13, what can be the reason?

**\node_modules\@angular\core\node_modules\tslib\tslib.es6.js:24
    export function __extends(d, b) {
    ^^^^^^

    SyntaxError: Unexpected token 'export'

Lonli-Lokli avatar Feb 22 '22 14:02 Lonli-Lokli

Hmm I haven't seen that one before, but I would start with checking your tsconfig for your tests (assuming this is in your tests considering you're reporting in jest-preset-angular). From there I'd compare to a newly generated app with Jest (Nx?) or see if I can trace or explain any differences in my Typescript configuration.

The missing of export suggests you don't have the right compilation settings, not the right libs are being loaded in or the target version is off.

Bjeaurn avatar Feb 22 '22 15:02 Bjeaurn

@Bjeaurn I take an example_v13 from this repository as an example and it's not reproduces there. But there are some differences for yarn install in them

  1. my repository with no yarn.lock & no node_modules produces node_modules/@angular/core/node_modules/tslib folder (which is mentioned in error)
  2. example_v13 do not have internal node_module at all

I do not know what can cause this behaviour? Both installs happens on same machine, same yarn, without yarn.lock & root node_modules

Lonli-Lokli avatar Feb 22 '22 17:02 Lonli-Lokli

@Lonli-Lokli I would open a separate issue for that, lest this thread become a place to post new issues.

The problem you're having is due to tslib requiring special handling. This is related to ESM vs CJS detection in jest, and the technique it uses doesn't match what tslib provides (I opened a bug on this in tslib). The fix is to override the path for tslib in moduleNameMapper - I'll post more info/workarounds if you open an issue.

johncrim avatar Feb 26 '22 16:02 johncrim

While converting an Angular 12 app from Jasmine I am seeing some strange issues like...

A "describe" callback must not return a value.

here is the test...

describe('PayCalendarsComponent', async () => {
  it.skip('do nothing', () => { });
});

jbeckton avatar May 26 '22 22:05 jbeckton

@jbeckton - your describe should not be async; move the async to the lambda in the it().

johncrim avatar May 26 '22 22:05 johncrim