jest-preset-angular
jest-preset-angular copied to clipboard
FAQ for issues and solutions which can appear
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:
-
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: () => ({})});
-
Q:
Could not find Angular Material core theme..
orCould 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"
],
},
- 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
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.
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.
in additional to first post
- 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
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.
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!
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,
}),
});
The solution above no longer works (at least not for me)
in you test you can set in providers this:
{
provide: MATERIAL_SANITY_CHECKS,
useValue: false
}
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?
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.
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",
},
};
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.
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.
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)
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.
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 🤔
The script is optional to use anyways :) Its purpose was to remind others not to “forget”to run ngcc
before running Jest.
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
I think nx
has a cache on test which somehow takes over or does something with Jest cache.
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
Seem like tslib
has changed something which makes the moduleNameMapper
in the preset not correct anymore. Thanks for the information 🙏
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
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
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 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 havenx
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
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.
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.
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 { }
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
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
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 :
Maybe someone already faced this problem ?
Thank you !
"@angular/core": "~12.2.10" "jest-preset-angular": "^10.0.1" "jest": "^27.3.0"
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 :
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"
//...
}
}
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.
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.
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'
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 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
- my repository with no yarn.lock & no node_modules produces node_modules/@angular/core/node_modules/tslib folder (which is mentioned in error)
- 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 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.
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 - your describe should not be async; move the async
to the lambda in the it()
.