"Error: spawn git ENOENT" when running react-scripts test - node.js

I have a project that I created using the create-react-app. When I first created the project the tests ran fine. I decided to run the tests after not running them for a while (I still haven't written any so the generated test class is all I have) and now I'm getting the following error:
Determining test suites to run...Error: spawn git ENOENT
at Process.ChildProcess._handle.onexit (internal/child_process.js:178:32)
at onErrorNT (internal/child_process.js:344:16)
at nextTickCallbackWith2Args (node.js:442:9)
at process._tickCallback (node.js:356:17)
Git is definitely on the path, I can run git --version from the command line and it outputs as expected. I get the same error if I run in cygwin or the windows command line.
My package.json looks like:
{
"name": "my-app",
"version": "0.1.0",
"private": true,
"dependencies": {
"immutable": "^3.8.1",
"react": "^15.5.4",
"react-dom": "^15.5.4"
},
"devDependencies": {
"react-scripts": "0.9.5"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}
EDIT: After some playing around I've discovered that my tests only fail when the project is in a git repository. If I take a copy of the project, without the '.git' folder then run the tests from the copy they all run fine.

I eventually figured out what was causing this. Something about my local setup is causing an error when git is launched as part of the Jest watcher (still not clear what). From the create-react-app docs:
By default, when you run npm test, Jest will only run the tests related to files changed since the last commit. This is an optimization designed to make your tests runs fast regardless of how many tests you have. However it assumes that you don’t often commit the code that doesn’t pass the tests.
Source
Running the tests as if they were running in a CI environment with set CI=true&&npm test bypasses the git functionality and I can run my tests. More information here
There is also an open bug in the jest project: https://github.com/facebook/jest/issues/3214

Related

Mocha and ts-node gives 'Unsupported Args'

In my package.json I have defined my test script:
"scripts": {
"test": "mocha --require ts-node/register ./test/**/*.ts",
"build": "npx tsc"
}
When I run npm test I get back the result:
> mocha --require ts-node/register ./test/**/*.ts
error: Unsupported Args: --require ts-node/register ./test/**/*.ts
It seems to somehow be the command interaction. Even if I run it manually node .\node_modules\mocha\bin\mocha --require ts-node/register "./test/**/*.ts" it fails with the same message. If I remove --require ts-node/register it runs, but fails when running the test on import statements because my test files are Typescript files.
How do I make mocha work with ts-node?
My package.json file has it in scripts
"scripts": {
"test": "./node_modules/mocha/bin/mocha -r ts-node/register tests/test.ts"
},
And after this I can run npm test and everything seems good.
Versions in devDependencies:
"devDependencies": {
"#types/chai-http": "^4.2.0",
"#types/expect": "^24.3.0",
"#types/mocha": "^9.0.0",
"#types/chai": "^4.2.18",
"#types/node": "14.14.30",
"chai": "^4.3.4",
"mocha": "^9.1.3",
"ts-node": "^9.1.1",
"typescript": "^4.4.4"
}
I was unable to find an answer to how to solve it with the command line, but I circumvented the problem by moving the options into package.json
"scripts": {
"test": "mocha"
},
"mocha": {
"extension": ["ts"],
"spec": "test/**/*.ts",
"require": "ts-node/register"
}
Update: I found the error. I was moving some code without test to having test. The logger was defined in a main.ts file which had some code that ran that was not behind any guard. In fact the error Unsupported Args was my own error message.
The act of referencing a winston logger caused the code in main.ts to run. For some reason this error does not happen now that the mocha options are in package.json even though the logger is still referenced which I find confusing. I am not sure why whether the options are directly in the command line, or they are in the package.json causes such a behavior difference. Regardless, the lesson learned is never reference into your main "running" module.

npm test -- --coverage never exits

I am using create-react-app to create a react application. When I executes npm test -- --coverage the test never exists. npm test actually runs react-scripts test. Any Idea?
-- --coverage part won't work, and should use one of the commands below to set CI to true.
By default npm test runs the watcher with interactive CLI. However, you can force it to run tests once and finish the process by setting an environment variable called CI.
source: React docs
Windows (cmd.exe)
set CI=true && npm test
set CI=true && npm run build
Windows (Powershell)
($env:CI = "true") -and (npm test)
($env:CI = "true") -and (npm run build)
Linux, macOS (Bash)
CI=true npm test
CI=true npm run build
NOT included in the docs
For Docker (node and react):
docker run -e CI=true [myImage] npm run test
Coverage won't work with Jest in watch mode.
Because "react-scripts test --env=jsdom" works in watch mode by default, the watch mode has to be switched off while generating the coverage output.
The following excerpt from the package.json contains a line "coverage" for illustration, how code coverage can be achieved within an app which was bootet by create-react-app.
It's just the modified "test" script, where the options --watchAll=false and --coverage are added in combination:
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"coverage": "react-scripts test --env=jsdom --watchAll=false --coverage",
"eject": "react-scripts eject"
}
Please note that it is obsolete to use standalone double-dash -- .
Most of the time this issue can be occur because of following reasons.
Not mentioning the required npm-script arguments in the
package.json file. If you use create-react-app to create your
react application, then it will not accept any command line
arguments. To resolve this problem, add following line under the
script tag in your package.json.
"test": "react-scripts test --coverage --watchAll", //mark --watchAll=false if you want.
Not mentioning the required jest configuration arguments in
the package.json or jest.config.js files. You should mention the files
which needed to include in your test coverage under the jest
configurations. Add following configurations in your
package.json.
package.json
"jest": {
"collectCoverageFrom": [
"src/**/*.js",
"!src/index.js", // files you need to avoid in test coverage
"!src/hooks/*.js",
"!src/context/*.js"
],
"coverageThreshold": {
"global": {
"branches": 90,
"functions": 90,
"lines": 90,
"statements": 90
}
},
"coverageReporters": [
"html",
"text"
]
},
Specifying a directory worked in my case
"test:cover": "react-scripts test --coverage src"
I tried all the solutions above, and for me it was still hanging with the message: Ran all test suites..
But this little hack helped:
"test:ci": "cross-env CI=true react-scripts test --forceExit --detectOpenHandles",
Explanation: The problem was coming from Jest not being able to close all processes. The above is a quick workaround. Ideally you should track the process that's stopping Jest from exiting.
In my case just added a new script "test:coverage": "react-scripts test --coverage"
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"test:coverage": "react-scripts test --coverage",
"eject": "react-scripts eject"
},

I am missing something about .env, could you explain it to me?

I have a very, basic, need: to store different endpoints for my APIs according to the environment. Suppose a simple file like this:
API_URL=http://localhost:8080
it should become, for my prod environment:
API_URL=http://myprodServer
and I'd like to have an integration test and a uat endpoint too!
Looking at my package.json I see:
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
So my idea is:
Put a command line argument near to "build" and "start" so to specify local and production enviroment files
Have a way to access to said configuration in my app, say config.API_URL
Now, I come from spring boot, and in spring boot I have a file per environment.
I though dotenv could be my solution but I see two strange things on their website:
Please don't commit your .env file --> so, how are my colleagues supposed to build my application? I usually at least push local and test environment, while keeping the uat and production files directly under the server
You should have just one .env file --> ok this one destroys me: if I just have one file how am I supposed to handle several environments???
What am I missing here? Could you help me solve my problem? I'm new to npm so I'm a little confused...
It looks like you are using CRA to develop your React app. If so, your env variables should be REACT_APP_API_URL=http://localhost:8080. Notice the prefix. If you are using CRA, you must use the prefix. More about that here. If you do this correctly, the variable should be available in your javascript by using process.env.REACT_APP_API_URL.
At work, we each have a copy of the .env files locally, since we don't check it in. We have different .env files for each environment - e.g - .env.production, .env.development, .env.stage. We then have a run and build script for each environment in our package.json. Using env-cmd package, our scripts might look like this:
{
...
...
"start": "react-scripts start",
"start:stage": "env-cmd .env.stage.local react-scripts start",
"start:production": "env-cmd .env.production.local react-scripts start",
"build": "react-scripts build",
"build:stage": "env-cmd .env.stage.local react-scripts build",
"build:development": "env-cmd .env.development.local react-scripts build",
...
...
}
Along with this, we also have a git branch per environment so that on stage branch we would run npm run build:stage and deploy to Stage environment. We would do the same for production.
After looking around for a multi-environment setup, this is what I settled on and it works ok. However, I'd be open to improving the process.

How to run npm start for reactjs even after closing terminal?

I've been following facebook tutorial with reactjs
I installed npm install -g create-react-app https://www.npmjs.com/package/react-scripts and created the app with it
But now I'm confuse how do I deploy my app to, for example, digital ocean? I know I can use pm2 to run a node server but I don't see how does npm start works as it just runs this in the package.json
{
"name": "hello-world",
"version": "0.1.0",
"private": true,
"devDependencies": {
"react-scripts": "0.7.0"
},
"dependencies": {
"babel-preset-es2015": "^6.18.0",
"babel-preset-react": "^6.16.0",
"express": "^4.14.0",
"mongoose": "^4.6.8",
"react": "^15.3.2",
"react-dom": "^15.3.2"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}
"start": "react-scripts start" what is it actually starting there?
also, it says that to build your app for deployment to use npm run build that just gives me a folder named build but I can't find anything to run node on.
I recommend reading the User Guide as it answers many common questions.
npm start starts the development server. It's only useful for development so you should never use it in production. This is printed in its output.
npm run build produces a static build folder with HTML, CSS, and JS files. You don't need Node to run it. It is static. To serve it, you would need to use any static file server. You can do this with Node, Python, Nginx, or any file server that can serve static files. This should also be printed in the command's output.
The deployment instructions vary depending on your hosting provider but basically you need to serve the build output from the server root, and you're set. If you use client-side routing you'll also want to configure your web server to serve index.html as a fallback for any path.
The user guide includes specific deployment instructions for different providers so check it out.

npm: how to run test & lint on each change?

I am using a bare npm ( no grunt/gulp) approach to develop my new MEAN project.
My config is like the following:
File package.json:
...
"start": "nodemon ./bin/www",
"lint": "jshint **/*.js",
"test": "mocha --recursive",
"dependencies": {
...
},
"devDependencies": {
...
},
Before starting, I run an npm start and nodemon starts monitoring my project tree for changes, triggering a restart after each source file change.
So far so good.
But what if I'd like to include - say - the lint and/or the test stages on each restart?
I didn't find any clue nor in the nodemon page nor in the npm one...
So you should have a definition of the start in your package.json to first run lint, then test then the actual run server.
You can find an example in following post:
http://substack.net/task_automation_with_npm_run
you should run the 'npm run monitor' command to start the monitoring and the restart should call the npm run start script.
but basically you want to have (based on your package.json)
"scripts": {
"start": "npm run lint & npm run test & node ./myfile.js",
"lint": "jshint **/*.js",
"test": "mocha --recursive",
"monitor": "nodemon ./bin/www"
.....

Resources