Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FAQ for issues and solutions which can appear #79

Open
timofei-iatsenko opened this issue Oct 9, 2017 · 44 comments
Open

FAQ for issues and solutions which can appear #79

timofei-iatsenko opened this issue Oct 9, 2017 · 44 comments

Comments

@timofei-iatsenko
Copy link

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

@timofei-iatsenko timofei-iatsenko changed the title Create a FAQ for issues and solutions which can appears Create a FAQ for issues and solutions which can appear Oct 9, 2017
@thymikee
Copy link
Owner

thymikee commented Oct 9, 2017

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.

@timofei-iatsenko
Copy link
Author

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.

@timofei-iatsenko
Copy link
Author

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 angular/angular#15127

@damoonrashidi
Copy link

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.

@sebald
Copy link

sebald commented Nov 10, 2017

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!

@timofei-iatsenko
Copy link
Author

timofei-iatsenko commented Nov 10, 2017

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,
    }),
});

@bhanna1693
Copy link

bhanna1693 commented Aug 17, 2021

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

@bdimir
Copy link

bdimir commented Aug 25, 2021

in you test you can set in providers this:

 {
    provide: MATERIAL_SANITY_CHECKS, 
    useValue: false
 }

@ahnpnl ahnpnl changed the title Create a FAQ for issues and solutions which can appear FAQ for issues and solutions which can appear Aug 25, 2021
@ahnpnl ahnpnl pinned this issue Aug 25, 2021
@joergplewe
Copy link

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?

@ahnpnl
Copy link
Collaborator

ahnpnl commented Sep 7, 2021

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.

@joergplewe
Copy link

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",
  },
};

@ahnpnl
Copy link
Collaborator

ahnpnl commented Sep 7, 2021

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.

@joergplewe
Copy link

joergplewe commented Sep 7, 2021

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.

@viceice
Copy link

viceice commented Sep 20, 2021

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 tslib@2.3.1

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)

@ahnpnl
Copy link
Collaborator

ahnpnl commented Sep 20, 2021

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.

@viceice
Copy link

viceice commented Sep 20, 2021

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 🤔

@ahnpnl
Copy link
Collaborator

ahnpnl commented Sep 20, 2021

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

@viceice
Copy link

viceice commented Sep 20, 2021

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

@ahnpnl
Copy link
Collaborator

ahnpnl commented Sep 20, 2021

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

@viceice
Copy link

viceice commented Sep 21, 2021

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

@ahnpnl
Copy link
Collaborator

ahnpnl commented Sep 21, 2021

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

@viceice
Copy link

viceice commented Sep 21, 2021

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

@ahnpnl
Copy link
Collaborator

ahnpnl commented Sep 21, 2021

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

@Bjeaurn
Copy link

Bjeaurn commented Sep 21, 2021

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.

@viceice
Copy link

viceice commented Sep 21, 2021

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 tslib@2.3.0 and i wrote above, it happened when I upgrade to tslib@2.3.1

tslib@2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e"
integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==

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

@ahnpnl
Copy link
Collaborator

ahnpnl commented Sep 21, 2021

I upgraded tslib to 2.3.1 #1025 but still couldn't see the same issue you had.

@nickroberts
Copy link

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.

@anatolie-darii
Copy link

anatolie-darii commented Sep 24, 2021

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

@MrTwisterAnastasia
Copy link

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

@ahnpnl
Copy link
Collaborator

ahnpnl commented Oct 5, 2021

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 angular/components#4125 (comment)

@Adrii77
Copy link

Adrii77 commented Oct 18, 2021

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"

@marcuskrahl
Copy link

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

@johncrim
Copy link
Contributor

johncrim commented Feb 2, 2022

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
Copy link
Contributor

johncrim commented Feb 2, 2022

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.

@Lonli-Lokli
Copy link

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'

@Bjeaurn
Copy link

Bjeaurn commented Feb 22, 2022

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.

@Lonli-Lokli
Copy link

@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

@johncrim
Copy link
Contributor

@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.

@jbeckton
Copy link

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', () => { });
});

@johncrim
Copy link
Contributor

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

@Trolejbus
Copy link

In last PrimeNg releases (> v16), they have added @layer primeng {} at-rule to their component's css stylesheets. And looks like JSDom cannot handle at-rules - it is throwing:

Error: Could not parse CSS stylesheet
          at exports.createStylesheet (C:\sources\creditboard-new\CreditBoard\ClientApp\node_modules\jsdom\lib\jsdom\living\helpers\stylesheets.js:34:21)
...
 detail: '@layer primeng{p-inputnumber,.p-inputnumber{display:inline-flex}...

Looks like JSDom is not supporting at-rules: jsdom/jsdom#2177.
So far preventing this error from showing up in console is working:

setup-jest.ts:

function hideJsdomCssParsingIssue() {
  const originalConsoleError = console.error;
  const jsDomCssError = 'Error: Could not parse CSS stylesheet';
  console.error = (...params) => {
    if (!params.find(p => p.toString().includes(jsDomCssError))) {
      originalConsoleError(...params);
    }
  };
}

But I am not sure how to fix entirely this issue.

@johncrim
Copy link
Contributor

@Trolejbus - I would look at the source for jsdom stylesheets.js. jsdom doesn't handle CSS, and doesn't do any layout. So it's not surprising that a DOM CSS method is stubbed out, thought I do find the error message a little surprising.

If you need layout (or CSS) support for your test, move it to karma.

@Trolejbus
Copy link

@johncrim - I have created issue for it: #2194. Case here is that it is sounds like not an issue with jest-preset-angular itself, but it will occur when installing most recent angular with most recent primeng version and trying to use jest-preset-angular. So I believe it is very common setup.

This issue is also reported for PrimeNg team: primefaces/primeng#14085

@MykhailoIskiv
Copy link

I've tried to migrate to es modules, as in v17 example, but haven't noticed performance improvements, it even work slower for me.
Maybe due to issues and how I've fixed it

  1. rxjs in moduleNameMapper
moduleNameMapper: {
  ...pathsToModuleNameMapper(tsconfig.compilerOptions.paths, { prefix: '<rootDir>' }),
  tslib: 'tslib/tslib.es6.js',
  rxjs: '<rootDir>/node_modules/rxjs/dist/bundles/rxjs.umd.js',
},

the issue is that overrides everything that has rxjs in path, for example angular rxjs-interop
the fix, is to check that it starts with rxjs ('^rxjs')

moduleNameMapper: {
  ...pathsToModuleNameMapper(tsconfig.compilerOptions.paths, { prefix: '<rootDir>' }),
  tslib: 'tslib/tslib.es6.js',
  '^rxjs': '<rootDir>/node_modules/rxjs/dist/bundles/rxjs.umd.js',
},
  1. rxjs/webSocket
    In my code I import webSocket from rxjs
    import { webSocket } from 'rxjs/webSocket';
    and for some reason it is not properly unwrapped in unit tests
    I get TypeError: webSocket is not a function error

when I log the webSocket, I get

webSocket {
  webSocket: [Function: webSocket],
  WebSocketSubject: [Function: WebSocketSubject]
}

instead of

webSocket [Function: webSocket]

Not sure that is a proper way to fix it, I've added the following to jest-global-mocks.ts

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

jest.mock('rxjs/webSocket', () => {
  return {
    ...(jest.requireActual('rxjs/webSocket') as object),
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    webSocket: (jest.requireActual('rxjs/webSocket') as any).webSocket
      .webSocket,
  };
});
  1. Issue with Leaflet and it's extension @geoman-io/leaflet-geoman-free
    For it I got issues like You are trying to import a file after the Jest environment has been torn down.
Test suite failed to run
ReferenceError: L is not defined

at node_modules/@geoman-io/leaflet-geoman-free/dist/leaflet-geoman.js:2:93715
at Object.<anonymous> (node_modules/@geoman-io/leaflet-geoman-free/dist/leaflet-geoman.js:2:225257)

I've fixed it by adding following to jest-global-mocks.ts

Object.defineProperty(window, 'L', {
  writable: true,
  value: jest.requireActual('leaflet'),
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests