Testing react app with enzyme , change rootDir - javascript

I have working on a react project to test my react app.
My root directory is /home for example
My react app is located in /home/MyApp/appModules/src/
inside all my *.js files implementing class
My react test app is located in /home/MyApp.tst/testModules/
In testModules/ directory, there is the package.json , and /src/ directory , tests directory, inside all my *.test.js [test file]
I am trying to change the root directory with configuration of package.json
"jest": {
"rootDir": [
"./../../"
]
},
but I have the error message when I run the command npm run coverage
react-scripts test --env=jsdom --coverage
Out of the box, Create React App only supports overriding these Jest options:
• collectCoverageFrom
• coverageReporters
• coverageThreshold
• globalSetup
• globalTeardown
• resetMocks
• resetModules
• snapshotSerializers
• watchPathIgnorePatterns.
These options in your package.json Jest configuration are not currently supported by Create React App:
• rootDir
If you wish to override other Jest options, you need to eject from the default setup. You can do so by running npm run eject but remember that this is a one-way operation. You may also file an issue with Create React App to discuss supporting more options out of the box.
If I eject the project with npm run eject, I can no more run es6 javascript test file ...
Have you any idea to help me ?
Thanks

The name already hints at the answer: user collectCoverageFrom to specify your directory /home/MyApp.tst/testModules/ if you want to keep this folder structure.
Or:
Move your tests and package.json within src and it should find them automatically

Related

test function is not recognized as a global function

I followed a JavaScript unit testing tutorial at acadamind.com in that tutorial instructor used Vitest for demonstrations and the reason they mentioned using Vitest instead of Jest was Jest needed some extra configuration to work with the latest JavaScript syntax.
After doing my own research about unit testing I realized industry demand unit testing skills with the Jest. So I followed another tutorial for learning unit testing with Jest and React Testing Library (RTL).
I created a brand new TypeScript project with Create React App (CRA) and followed the instructions in that tutorial and everything went well. The instructor mentioned that Jest and RTL are supported out of the box with CRA.
After studying unit testing I tried to apply that knowledge and write some tests with my application, which was created some time back, and recently we updated it to React Scripts 5. In that application, I check node_modules folder, and Jest is there as a dependency. But I have noticed that the following packages are not listed in the package.json file in my project, so I installed them:
#testing-library/jest-dom": "^5.16.5",
#testing-library/react": "^13.4.0",
#testing-library/user-event": "^14.4.3",
#types/jest": "^29.4.0",
After that, I noticed my new project has this file in the src folder so I have copy pasted this file as well.
setupTest.ts
// jest-dom adds custom jest matchers for asserting on DOM nodes.
// allows you to do things like:
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import '#testing-library/jest-dom';
When I tried to run when I tried to write my first unit test I noticed that VS Code doesn't recognize this test function as a global function and indicates an error and then I try to run the test script and I am getting this error
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/pathum/Documents/tagd/node_modules/axios/index.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import axios from './lib/axios.js';
^^^^^^
SyntaxError: Cannot use import statement outside a module
> 1 | import axios from 'axios';
| ^
2 | // config
3 | import { HOST_API } from '../config';
4 |
at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1728:14)
at Object.<anonymous> (src/utils/axios.ts:1:1)
at Object.<anonymous> (src/hooks/useRefresh.tsx:2:1)
at Object.<anonymous> (src/hooks/useAxiosPrivate.tsx:3:1)
at Object.<anonymous> (src/pages/contracts/contract-form/new-contact-person.tsx:12:1)
at Object.<anonymous> (src/pages/contracts/contract-form/parties.tsx:15:1)
at Object.<anonymous> (src/pages/contracts/contract-form/contract-form.tsx:9:1)
at Object.<anonymous> (src/pages/contracts/contract-form/contract-form.test.tsx:2:1)
at TestScheduler.scheduleTests (node_modules/#jest/core/build/TestScheduler.js:333:13)
at runJest (node_modules/#jest/core/build/runJest.js:404:19)
Test Suites: 1 failed, 1 total
Tests: 0 total
Snapshots: 0 total
Time: 2.398 s
Ran all test suites related to changed files.
Watch Usage: Press w to show more.
Seems I need to do some configurations for Jest to work properly in the application. How do I fix this?
Install the necessary dependencies: npm install --save-dev #babel/preset-typescript and npm install --save-dev jest-cli typescript
Create a new file in the root of your project called jest.config.js and add the following content to it:
preset: 'ts-jest',
testEnvironment: 'node',
testMatch: ['**/*.test.ts'],
};
Add a new property called "jest" to the "scripts" section of your package.json file and set it to the following: "jest --config jest.config.js --coverage". This will tell Jest to use the configuration file you just created and also generate a coverage report.
Create a new file in the root of your project called tsconfig.test.json and add the following content to it:
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./test-dist"
},
"include": [
"src/**/*.test.ts"
]
}
Finally, you can run your tests with npm run jest.
You also need to make sure that you are using import statement correctly in your tests. You should use import statement to import functions, classes, and variables from other modules, but you should use require statement to import modules that are not written in TypeScript.

Jest not recognising JQuery Object ($)

I have used JavaScript to created a simple web application to measure how much time I spend on different projects.
I want to test the code with Jest and this works fine until I try to test a function that contains the JQuery object ($).
This is the error message I get:
ReferenceError: $ is not defined
The answers I have found online tells me that I need to add a jQuery dependency in my global object, which I have done. Below is my package.json file:
"jest": {
"setupFiles": ["PathToSetupFile/setup-jest.js"],
"type": "module"
and my setup-jest.js:
import $ from 'jquery';
global.$ = global.jQuery = $;
I am now met with a new error message:
SyntaxError: Cannot use import statement outside a module
I cannot find any further information on how to fix this. A few resources tell me I need to update my jest.config.js file but this file does not exist anywhere in my node modules.
I thought it would be helpful to start completely from the beginning and therefore address a much wider scope but never the less provide the exact answer to your problem at the end of my response here.
In PowerShell CD to your project folder
Install the jest node modules locally into your project folder using
npm install --save-dev jest
Install jest globally so you can use it as a CLI command
npm install jest -g
This installs Jest globally i.e. to your user profile %APPDATA%\npm location
Ensure %APPDATA%\npm is in your user profile environment PATH variable (in Windows settings, "Edit Environment variables for your account")
Check in your PowerShell console that it is in your path using $Env:PATH. (If your %APPDATA%\npm path still isn't showing then restart the PowerShell window, if the terminal is inside VSCode then you will have to restart VSCode so that the terminal inherits the new environment)
In order to import jquery you will need to a) install jquery and b) define a setup file for jest which is referenced in jest.config.js created using jest --init in your project folder.
Install jquery -
npm install --save-dev jquery
Generate jest.config.js -
jest --init
The following questions will help Jest to create a suitable configuration for your project
√ Would you like to use Typescript for the configuration file? ... no
√ Choose the test environment that will be used for testing » jsdom (browser-like)
√ Do you want Jest to add coverage reports? ... yes
√ Which provider should be used to instrument code for coverage? » v8
√ Automatically clear mock calls, instances, contexts and results before every test? ... yes
✏️ Modified your\project\folder\package.json
📝 Configuration file created at jest.config.js
If you don't specify the jsdom (browser-like) test environment then running code under test that uses jquery will yield an error of "jQuery requires a window with a document"
But this means the 'jest-environment-jsdom' must now be installed
(As of Jest 28 "jest-environment-jsdom" is no longer shipped by default, make sure to install it separately.) -
npm install --save-dev jest-environment-jsdom
Edit jest.config.js
Change
// setupFiles: [],
To
setupFiles: [ './jest.setup.js' ],
N.B. the "./" prefix is required otherwise jest will state it cannot find the jest.setup.js file.
The create jest.setup.js in your project folder and add the following -
const $ = require('jquery');
global.$ = global.jQuery = $;
Node uses the CommonJS module system (https://nodejs.org/en/knowledge/getting-started/what-is-require/)
so the above syntax is required to work with Node.js

One react app imported into another react app?

Is it possible to import one React app(built using create-react-app) into another completely different React app. We all have imported components in our SPA, but is it possible to import a different app entirely? If so how?
Furthermore, both these react apps MIGHT share a few similar dependencies/files/libraries.. such as bootstrap/css/Redux stores/etc. Also, with a possibility of a few common reducers. These common reducers, might need to interact/listen to actions in-between these two react app.
Lets say we have:
ReactDOM.render(<Provider store={store}><MainApp /></Provider>, document.getElementById('root'));
Could i add another app like this(that was NOT built in this), and target another nod in the dom???
ReactDOM.render(<Provider store={store}><ExternalAPP /></Provider>, document.getElementById('root22'));
Has this ever been done before? React compresses all our components into "chunks" which are basically js files.
Thank you, for any tips/suggestions/hints
You can use npm pack command.
It creates a tarball (.tgz) file from your current app. Then move this file your other app folder then run:
npm install app1 (assuming app1 is your first app name).
After it is installed, you can see your app1 files inside the node_modules/App1/. Now your can import the files or components you want and use it in other apps.
Hope this helps.
Also Checkout this: https://docs.npmjs.com/cli-commands/pack.html
One way that worked for me is to bring the CRA to Github and npm install it as a dependency. I highly encourage you to check out this resource which explains in detail how to prepare a React component for this process. Follow the steps in the linked tutorial up to #3, then bring everything (including the /dist folder) to Github. Then, do npm install org_name/repo_nameand install it as a dependency in your second React app. Then, to import a specific component, you can do something like import { Button } from 'repo_name/dist/index' or reference whatever file you used to export your components.
In case the link doesn't work, here are the steps in the article:
Create a folder called lib that stores all the components you want to bring to the other react app. Also define a file called index.js in this folder that exports these components.
Create a repo for the components on Github
Install Babel and build the dist folder.(npm install --save-dev #babel/core #babel/cli #babel/preset-env and npm install -save #babel/polyfill)
Add the following config file to the top-level folder of your project:
{
"presets": [
[
"#babel/env",
{
"targets": {
"edge": "17",
"firefox": "60",
"chrome": "67",
"safari": "11.1"
},
"useBuiltIns": "usage",
"corejs": "3.6.5"
}
],
"#babel/preset-react"
]
}
In package.json, replace the build script with the following: "build": "rm -rf dist && NODE_ENV=production babel src/lib --out-dir dist --copy-files";
Run the command npm run build

vue cli build with target lib: "require is not defined" when component is imported

I'm trying to export a Vue component as a package, and using vue cli to build the dist. I intend to publish it on npm, but I'm currently using a symbolic link for testing purpose. However even with a simple hello-world project I can't make a valid package.
I created a project:
vue create hello-world
Then I modified the package.json:
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build --target lib --name vue-hello-world ./src/components/HelloWorld.vue",
"lint": "vue-cli-service lint"
},
"main": "./dist/vue-hello-world.common.js",
Then I call
npm run build
and it compiles without error.
Then I make an import in a vue component in another project (I used a symbolic link in node_modules):
import HelloWorld from "hello-world";
On page render I get the following error:
[Vue warn]: Failed to resolve async component: function MediaViewerPdf() {
return Promise.all(/*! import() */[__webpack_require__.e(62), __webpack_require__.e(46)]).then(__webpack_require__.bind(null, /*! ./viewers/MediaViewerPdf.vue */ "./vuejs/components/mediaViewer/viewers/MediaViewerPdf.vue"));
}
Reason: ReferenceError: require is not defined
Any idea what's happening?
Remarks:
using vue inspect, I checked that in webpack config that:
target: "web"
I already set resolve.symlinks at false on the importing project.
EDIT: I have confirmed that it doesn't come from the symbolic link, I have exactly the same error with package directly on node_modules.
Repo with whole code: https://github.com/louis-sanna/vue-hello-world
So I asked the question on the vue-cli repo and I got the solution! https://github.com/vuejs/vue-cli/issues/4245
Turns out NODE_ENV was already set at development in my shell, so it was the mode used to make the build.
Just need to set the mode explicitly and it works:
vue-cli-service build --target lib --name vue-hello-world ./src/components/HelloWorld.vue --mode production
You may need to add it to vue.config.js:
config
.mode("production")
This happens due to the fact that Vue CLI Webpack setup by default does not import commonjs modules, as described in your "main" field in package.json. So the problem is with the project that attempts import, not with the project that exports the component.
There are two ways to attempt to solve this problem.
From the importing project side
You can remedy this by installing babel plugins for the project that imports your components and setting babel.config.js
module.exports = {
presets: [
'#vue/app'
],
plugins: [
'#babel/plugin-transform-modules-commonjs', // leave to import .common.js files
'#babel/plugin-transform-modules-umd' // leave to import .umd.js files
]
}
But doing this alone will not be sufficient: you also will need to import CSS that is generated with the library by adding this in your entry file
import 'hello-world/dist/vue-hello-world.css';
Note that I have only tested this using yarn link, but I have confidence that this will work with an imported separate npm module just fine.
From the library side
The intent (I suppose) of the original question - how do I bundle a library so my users don't have to do this little dance each time they want to use it?
Option 1: don't bundle it - provide .vue files and sources. Just include everything in 'src' directory of your module, write a readme with explanation and be done with it. Let the importing project figure the compilation and bundling out.
Option 2: use rollup with Vue plugin to roll components into bundle. There is an example on how to do that. In that example you can see that your project will be able to import .esm build
https://github.com/vuejs/rollup-plugin-vue/tree/master/cookbook/library
Not sure how you are creating the symbolic link, but you should use npm link for that. If you are still having problems (like I did myself) I would suggest you try npm-link-better:
npm install -g npm-link-better
cd vue-hello-world
npm link
cd ../hello-world
nlc -w vue-hello-world
For building component libraries, I suggest you have a look at vue-cli-plugin-component. This plugin already sets up the vue-cli project pretty well.

How is import assets from './assets' resolved in React Starter Kit

In the server.js the assets are imported like this
import assets from './assets';
If I understood it correctly this path maps to build/public/assets which is generated through the webpack configuration here:
output: {
path: path.resolve(__dirname, '../build/public/assets'),
publicPath: '/assets/',
sourcePrefix: ' ',
pathinfo: isVerbose,
},
Or am I mistaken on that? When I run webpack I still run into:
ERROR in ./src/server.js
Module not found: Error: Cannot resolve 'file' or 'directory' ./assets
Basically the question here is not how to get it run, but why can the line import assets from './assets'; in the React Starter Kit be resolved even though there is no assets.js inside src.
you need to build the project first:
npm run build
this creates the build folder with the assets.js file in it.
Check out the webpack.config.js file in the /tools folder.
It's using assets-webpack-plugin to bundle assets into namespaced client and vender modules.
After running npm run build, webpack outputs the resulting builds to the build/public/assets folder. Since the src/server.js is referencing ./assets as a relative, not fixed path, it will work once it's bundled and you run server.js from the build/public dir.
This ReadMe is also helpful: Build Automation Tools.

Categories

Resources