Error 'Missing: SyncTestZoneSpec' during karma test with angular 4 - javascript

First thing first : my project is totally sane on branch /develop with test passing and all.
I created a branch to clean imports and use aliases instead of ../../../../ each time I have to access classes. I added it into tsconfig.json :
"baseUrl": "src",
"paths": {
"#app/*": [
"app/*"
],
"#core/*": [
"app/core/*"
],
"#common/*": [
"app/common/*"
],
"#models/*": [
"app/models/*"
],
"#env/*": [
"environments/*"
],
"#assets/*": [
"assets/*"
]
}
I just finished but when executing the test with simple npm run test which do something like thiis is think karma start ./karma.conf.js --log-level error I get this error :
HeadlessChrome 67.0.3396 (Windows 10.0.0) ERROR
Uncaught Error: Missing: SyncTestZoneSpec
at http://localhost:9876/_karma_webpack_/vendor.bundle.js:270128
All I have changed is what I told above, what is this error telling me ?
EDIT : Correction with github links
Corrected this issue by updating the zone.js version to 0.8.26 and replaced the imports in test.ts by only one line :
import 'zone.js/dist/zone-testing';
But now I get this error for all tests :
HeadlessChrome 67.0.3396 (Windows 10.0.0) SomeService #getCurrentUser should return user object FAILED
TypeError: Cannot read property 'assertPresent' of undefined
at resetFakeAsyncZone node_modules/#angular/core/#angular/core/testing.es5.js:308:1)
at Object.<anonymous> node_modules/#angular/core/#angular/core/testing.es5.js:1015:1)
at ZoneQueueRunner.webpackJsonp../node_modules/zone.js/dist/zone-testing.js.jasmine.QueueRunner.ZoneQueueRunner.execute node_modules/zone.js/dist/zone-testing.js:437:1)
HeadlessChrome 67.0.3396 (Windows 10.0.0): Executed 120 of 120 (120 FAILED) ERROR (4.725 secs / 4.633 secs)
Relatedd issue on github but no solution for now.
The content of my test.ts :
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
import { getTestBed } from '#angular/core/testing';
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '#angular/platform-browser-dynamic/testing';
import 'zone.js/dist/zone-testing';
// Unfortunately there's no typing for the `__karma__` variable. Just declare it as any.
declare const __karma__: any;
declare const require: any;
// Prevent Karma from running prematurely.
__karma__.loaded = function () {};
// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(
BrowserDynamicTestingModule,
platformBrowserDynamicTesting()
);
// Then we find all the tests.
const context = require.context('./', true, /\.spec\.ts$/);
// And load the modules.
context.keys().map(context);
// Finally, start Karma to run the tests.
__karma__.start();

Try moving the zone-testing import up to be one of the first imports like this:
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
import 'zone.js/dist/zone-testing';
import { getTestBed } from '#angular/core/testing';
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from
'#angular/platform-browser-dynamic/testing';
Taken from this bug report: All tests failed if order of imports is changed in test.ts

Related

Jest ReferenceError on globally defined JS constants within Angular components

Today I've started using Jest to UnitTest some of our TypeScript files within our Angular project. After the initial Jest setup was done, creating a test for a pure TypeScript method in our util.ts was pretty straight-forward. Now I'm working on testing something in an Angular component, and I'm encountering an error because of our global constants within an imported other Component. So I'm looking for a way to either:
Give a default to these global variable in my Jest UnitTest class itself by setting them in a beforeAll.
Have a (separated) custom-jest-constants.setup.ts file to predefine all global variables for all tests
I'll save you the details of the steps I did this morning to setup and configure Jest within Angular, but I ended up with the following relevant changes because of it:
Within the angularelements/ root folder:
Added jest.config.ts:
export default {
clearMocks: true,
globalSetup: 'jest-preset-angular/global-setup',
preset: 'jest-preset-angular',
setupFilesAfterEnv: ['<rootDir>/setup-jest.ts'],
};
Added setup-jest.ts:
import 'jest-preset-angular/setup-jest';
Added tsconfig.spec.json:
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/spec",
"module": "CommonJs",
"types": ["jest"]
},
"include": ["src/**/*.spec.ts", "src/**/*.d.ts"]
}
Modified package.json:
{
...,
"scripts": {
...,
"test": "jest"
},
"devDependencies": {
...,
"#types/jest": "^28.1.3",
"jest": "^28.1.1",
"jest-preset-angular": "^12.1.0"
}
}
Within a new test folder:
Added util.test.ts and question.component.test.ts, what they do isn't too relevant.
The error I'm getting when I run npm test:
PASS test/app/util.test.ts
FAIL test/app/questionnaire/runtime/question/question.component.test.ts
● Test suite failed to run
ReferenceError: maxFileUploadSizeInKb is not defined
42 | ...
> 43 | private static readonly UPLOAD_LIMIT_IN_BYTES = +maxFileUploadSizeInKb * 1000;
| ^
44 | private static readonly IMAGE_UPLOAD_LIMIT_IN_BYTES = +maxImageFileUploadSizeInKb * 1000;
45 | ...
at Object.<anonymous> (src/app/document-panel/document-uploading/document-uploading.component.ts:43:52)
at Object.<anonymous> (src/app/questionnaire/runtime/questionnaire-document-panel/questionnaire-document-panel.component.ts:10:1)
at Object.<anonymous> (src/app/questionnaire/runtime/question/question.component.ts:16:1)
at Object.<anonymous> (test/app/questionnaire/runtime/question/question.component.test.ts:1:1)
As for the relevant code within the document-uploading.component.ts:
declare const maxFileUploadSizeInKb: string;
declare const maxImageFileUploadSizeInKb: string;
#Component({ ... })
export class DocumentUploadingComponent extends ... {
private static readonly UPLOAD_LIMIT_IN_BYTES = +maxFileUploadSizeInKb * 1000;
private static readonly IMAGE_UPLOAD_LIMIT_IN_BYTES = +maxImageFileUploadSizeInKb * 1000;
Those declared constants are global constants that we define in our javascriptPre.jspf:
...
<script ...>
var maxFileUploadSizeInKb = '<%=Util.parseInt(SettingManager.get(Setting.maximumFileSizeInKb), Setting.DEFAULT_MAX_FILE_SIZE_KB)%>';
var maxImageFileUploadSizeInKb = '<%=Util.parseInt(SettingManager.get(Setting.maximumImageFileSizeInKb), Setting.DEFAULT_MAX_IMAGE_FILE_SIZE_KB)%>';
</script>
...
Which will basically inject the settings we've defined in our Java backend to this globally defined JS variable, which is accessible within our Angular/Typescript classes as can be seen in the document-uploading.component.ts.
If I temporarily modify the DocumentUploadingComponent to hard-coded constants like this:
private static readonly UPLOAD_LIMIT_IN_BYTES = 5_000_000;
private static readonly IMAGE_UPLOAD_LIMIT_IN_BYTES = 400_000;
Everything works as intended when I run npm test.
So, back to the original question: how could I overwrite/setup the maxFileUploadSizeInKb/maxImageFileUploadSizeInKb to some default value, either within a custom Jest setup file or in a beforeAll within my UnitTest file (or elsewhere perhaps)?
Right after I posted my answer above I finally found the solution, which was simpler than I thought.
In jest.config.ts I've added:
setupFiles: ['<rootDir>/custom-jest-setup.ts'],
And in that added new custom-jest-setup.ts file within my angularelements/ folder I've used:
// #ts-ignore
global.maxFileUploadSizeInKb = 5000;
// #ts-ignore
global.maxImageFileUploadSizeInKb = 400;
And that's it. My UnitTests run without any issues now!

jest Cannot find modules inside node_modules folder when using swc compiler (Next,js)

I have a project with Next.js and wanted to do some unit tests on it.
I followed the instruction provided here and managed to make some tests. it's also good to mention that I'm using the rust compiler and typescript for the project.
but there is an issue with one of the tests when loading a module from the node_modules folder. here is the output:
$ jest
info - Loaded env from /Projects/projectname/.env
PASS test/pages/index.test.tsx
PASS components/shared/ui/Button/Button.test.tsx
FAIL components/shared/ui/Card/Card.test.tsx
● Test suite failed to run
Cannot find module 'swiper/react' from 'components/attraction/Gallery/Gallery.tsx'
Require stack:
components/attraction/Gallery/Gallery.tsx
components/attraction/Gallery/index.ts
components/attraction/index.ts
components/index.ts
components/shared/ui/Card/Card.tsx
components/shared/ui/Card/Card.test.tsx
1 | import { IImageResponse } from '#/constants'
2 | import React, { useState } from 'react'
> 3 | import { Swiper, SwiperSlide } from 'swiper/react'
| ^
4 | import SwiperCore, { Pagination } from 'swiper'
5 | import styles from './Gallery.module.scss'
6 |
at Resolver.resolveModule (node_modules/jest-resolve/build/resolver.js:324:11)
at Object.<anonymous> (components/attraction/Gallery/Gallery.tsx:3:51)
anything other than the components inside the project gives me this error.
here is the jest config for the project:
const nextJest = require('next/jest')
const createJestConfig = nextJest({
// Provide the path to your Next.js app to load next.config.js and .env files in your test environment
dir: './',
})
// Add any custom config to be passed to Jest
const customJestConfig = {
setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
moduleNameMapper: {
// Handle module aliases (this will be automatically configured for you soon)
'^#/(.*)$': '<rootDir>/$1',
},
testEnvironment: 'jest-environment-jsdom',
}
// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
module.exports = createJestConfig(customJestConfig)
can anyone help as to why this is happening?

Jest encountered an unexpected token - SyntaxError: Unexpected token 'export'

I'm using jest to test a react TypeScript app.
This is the test I'm running:
import { render, screen } from '#testing-library/react'
import { toBeInTheDocument } from '#testing-library/jest-dom'
import ContextProvider from '../../context/ContextProvider'
import { BrowserRouter } from 'react-router-dom'
import BlogPage from './BlogPage'
describe('BlogPage', () => {
test('Render blog page', () => {
render(
<ContextProvider>
<BrowserRouter>
<BlogPage/>
</BrowserRouter>
</ContextProvider>
)
expect(screen.getByText('In this page you can see some of the last articles I wrote.')).toBeInTheDocument()
})
})
And this is the error I'm getting:
FAIL src/components/blogPage/BlogPage.test.js
● Test suite failed to run
Jest encountered an unexpected token
Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.
Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.
By default "node_modules" folder is ignored by transformers.
Here's what you can do:
• If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it.
• If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
• If you need a custom transformation specify a "transform" option in your config.
• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/configuration
For information about custom transformations, see:
https://jestjs.io/docs/code-transformation
Details:
/home/German/Desktop/ger/code/projects/my-website/node_modules/react-markdown/index.js:6
export {uriTransformer} from './lib/uri-transformer.js'
^^^^^^
SyntaxError: Unexpected token 'export'
> 1 | import ReactMarkdown from 'react-markdown'
| ^
2 | import Accordion from 'react-bootstrap/Accordion'
3 |
4 | interface Props {
I understand this is because the library I'm using (react-markdown) doesn't have pre-compiled source code. The thing is I followed the docs (https://jestjs.io/docs/tutorial-react-native#transformignorepatterns-customization) and added the react-markdown folder to the transformIgnorePatterns config and I still get the error.
This is my jest.config.ts file:
import type { Config } from '#jest/types'
const config: Config.InitialOptions = {
verbose: true,
transform: {
'^.+\\.ts?$': 'ts-jest'
},
transformIgnorePatterns: [
'node_modules/(?!react-markdown/)'
]
}
export default config
I tried adding <rootDir> like <rootDir>/node_modules/(?!react-markdown/) and It didn't make a difference.
I also tried configuring jest directly from package.json instead of a jest.config file and It didn't make a difference either.
Then I found this question: Jest transformIgnorePatterns not working, which mentions you need to configure Babel.
I created my app with create-react-app so I didn't have Babel on my app. I installed it and created a babel.config.js file inside of which I put:
module.exports = {
"presets": [
"#babel/preset-env"
]
};
But I still get the error...
I'm running out of ideas. Any clue of how could I solve this?
Full code can be found here: https://github.com/coccagerman/my-website
react-markdown is shipped as js, add babel-jest as a transformer in your jest config
transform: {
'^.+\\.ts?$': 'ts-jest',
"^.+\\.(js|jsx)$": "babel-jest"
},

TypeError: multi is not a function / default import from rollup-plugin-multi-input does not work from ESM package

I found a plugin rollup-plugin-multi-input which fixes the problem of not being able to specifiy a glob to the test rollup config. For the unt tests, the entry point is not a single entity from which an import graph can be derived. It is just a collection of source files containing tests, which doesnt fit input requirement of rollup.
However, my attempt at trying to use it was fruitless:
rollup-config.tests.mjs:
import multi from 'rollup-plugin-multi-input';
const testConfig = {
input: ['test/**/*.spec.ts'],
external: ["chai", "mocha", "dirty-chai"],
output: {
format: "es",
file: `dist/${name}-bundle.test.js`,
plugins: [],
sourcemap: true
},
plugins: [
multi(),
resolve(),
commonjs(),
typescript({
tsconfig: "./tsconfig.test.json"
})
],
}
just resulted in this error:
[!] TypeError: multi is not a function
TypeError: multi is not a function
Looking at the exported code from the plugin, I can see that the default export is a function:
var _default = function(param) {
}
exports.default = _default;
So I don't know why this doesnt work.
I since discovered that there is another plugin that does a similar thing: #rollup/plugin-multi-entry:
import entry from "rollup-plugin-multi-entry";
plugins: [
entry(),
resolve(),
commonjs(),
typescript({
tsconfig: "./tsconfig.test.json"
})
],
so configured and invoked in exactly the same way, but now it works in the way that I wanted it to; the test bundle is created and mocha indeed sees all the tests and executes them successfully.
So let's take a look at that export and see if there is a difference in what is exported:
Well the first thing to notice is that its dist folder contains a .mjs file and a .js file. Since we're importing from an ESM package ("type": "module" in package.json), I guess we're using the default export from the .mjs file:
function multiEntry() {
...
}
export default multiEntry;
With rollup-plugin-multi-input, I even tried using the createRequire from "module":
import { createRequire } from "module";
const require = createRequire(import.meta.url);
const multi = require('rollup-plugin-multi-input');
but that failed for the same reason.
So whats the problem here? Why does default import from rollup-plugin-multi-input not work?

React Native - unexpected token static propTypes when running assmbleRelease, babel plugin doesnt work

I'm trying to compile a release apk in React Native using either
"react-native run-android --variant=release" or
from ./android:
"./gradelw assmbleRelease"
I keep getting the following error:
> :app:bundleReleaseJsAndAssets
ERROR Failed to compile.
./node_modules/native-base-shoutem-theme/src/StyleProvider.js 10:19
Module parse failed: Unexpected token (10:19)
You may need an appropriate loader to handle this file type.
| */
| export default class StyleProvider extends React.Component {
> static propTypes = {
| children: PropTypes.element.isRequired,
...
I've installed this plugin:
https://babeljs.io/docs/en/next/babel-plugin-proposal-class-properties.html
and added it to my babel.config.js:
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
plugins: [
'#babel/plugin-proposal-class-properties'
]
};
I've tried creating also a .babelrc file and setting it up. didn't work.
I tried configurating babel through package.json and also it didn't work.
I've tried doing
"react-native start -- --reset-cache"
but nothing helped. I keep getting the same error.
I know the babel.config.js is being read because if I mess around with it I see that the build fails for other reasons.
but a strange thing is that if I remove the file completely, I still get the original error (missing "static propTypes" thing).
why doesn't the plugin work?
Not sure why this happened, but removing "haul" did the trick.
"npm uninstall --save-dev haul"
and remove the added config in app/build.gradle:
project.ext.react = [
cliPath: "node_modules/haul/bin/cli.js"
]

Categories

Resources