Yarn "posttest" script does not work if "test" script fails - node.js

Well, I have these scripts in my package.json for testing some code in NodeJS.
"scripts": {
"pretest": "env NODE_ENV=test sequelize db:migrate",
"test": "jest",
"posttest": "env NODE_ENV=test sequelize db:migrate:undo:all"
}
When the tests go clear, the "posttest" runs, but when the tests fail, I receive a
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
in VS Code. There is nothing usefull on the link about the problem, neither on the internet.
So I found this link about NPM:
https://github.com/npm/npm/issues/5493
The guy said:
In the vast majority of cases, users are going to be unpleasantly
surprised if posttest runs after test failures (you don't want your
test environment being cleaned up or new versions being published if
there were test failures, for instance). As such, this behavior isn't
going to change. Putting something like "test":"npm run-script
test-failing || npm run-script mandatory-cleanup" into your
package.json will give you what you want.
This did not solve my problem. With more research I found this:
npm posttest doesn't trigger if npm test fails
The solutions did not work for me either.
So how can I run the "posttest" script even if the tests fail?

Well, with the conversation above, I got to this solution:
This is my scripts in package.json:
"scripts": {
"dev": "nodemon src/server.js",
"pretest": "env NODE_ENV=test sequelize db:migrate",
"run-tests": "jest",
"run-after-tests": "env NODE_ENV=test sequelize db:migrate:undo:all",
"test": "npm-run-all run-tests run-after-tests --continue-on-error"
},
I installed the npm-run-all package and it runs the run-after-test script even if the tests fail. Now I get the errors
error Command failed with exit code 1.
from the test script, and
ERROR: "test" exited with 1.
error Command failed with exit code 1.
from run-after-test, but in the end my problem got solved. If someone has a better solution with no errors at the end of the scripts, please share with us.

Related

Difference between start and dev script in package.json file

In almost all of the docs I've come across so far, most of the time I have seen the start and the dev script being used for a similar kind of functionality. following are 2 examples:
1.
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node index",
"dev": "nodemon index"
},
"scripts": {
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"start": "npm run dev",
So, please help me in understanding, what exactly is the difference between the two in package.json file used for NodeJs. Under what circumstances does mentioning the 2 at the same time make sense.
P.S: I'm new to javascript and node.js. Hence please forgive in case of a silly mistake. Thanks in advance :)
Start is a script handled by default by npm. You can use it without the keyword run:
npm start
dev is a custom script, the name has no significance fr npm. You need to use the keyword run:
# npm run <script name>
npm run dev
documentation for start: https://docs.npmjs.com/cli/v6/commands/npm-start
documentation for run-script: https://docs.npmjs.com/cli/v6/commands/npm-run-script
In other words, start will override the default npm command. By default, npm will run node index.js on start. The start script always exists even if you don't declare it. That is not the case for dev.

Run a single test file using Node js Mocha

All my tests are under test folder and when I give npm test all the tests are getting executed. Now I am trying to run my test scripts by file or by it's describe. I have the following in my package.json
"scripts": {
"test": "set NODE_ENV=test&& nyc --reporter=html --reporter=text mocha 'test/**/*.js' --exit --timeout 7000"}
When I give npm test --grep 'filename / describe / it' it is not picking up the given input instead I'm getting the following warning Warning: Cannot find any files matching pattern "given filename / describe /it" even though given input matches.
My filename pattern is filename.test.js and the folder structure is like test\***\filename.test.js
Can anyone guide me on what I'm missing on this.
You need to include the grep option within the npm command:
"scripts": {
"test": "set NODE_ENV=test&& nyc --reporter=html --reporter=text mocha 'test/**/*.js' --exit --timeout 7000 --grep"
}
Then call it with:
npm run test <name of test>

How to wait for server start complete from an npm script?

I'm trying to run a functional test for a node app.
In my package.json I have the following scripts:
"scripts": {
"web-server": "NODE_ENV=test node app.js &",
"test": "npm run web-server && mocha ./tests/functional/*.js --exit",
"posttest": "pkill -f node"
}
But when running it, tests run before the server completes starting.
How can I wait for the server?
I found wait-on today and like its approach. It only does the wait, not other things like command launching.
Using it with concurrently, like so:
"scripts": {
"xxx": "concurrently -n server,mocha \"npm run web-server\" \"npx wait-on http://localhost:8080 && npx mocha ...\"",
Wanted to mention to new visitors. I think wait-on is currently the best fitting answer to the title's question.
As far as I understand,
you'd like to run your local server, once the server is up tests cycle should be triggered.
I suggest to use the package "start-server-and-test" sounds suite for your solution, the NPM package page is here
Let's take your current package.json script object, and rewrite them.
The start and test scripts are the two basic scripts you need to maintain your app easily.
start - to start your app (I suggest to use nodemon or pm2)
test - call your test script
Notes:
To dev tests you will need to handle two terminals, each for the above.
I'm assuming you're running on port 8080
The package is also handling the termination of both processes (node and mocha) in both cases success and failure so no need (posttest:ci, --exit, etc..)
There is no need to use child process (the &) that mentioned at the end of your web-server package.json's script.
Here is the new script object, from my POV
"scripts": {
"start": "node app.js",
"test": "NODE_ENV=test mocha ./tests/functional/*.js",
"test:ci": "NODE_ENV=test start-server-and-test start \"http://localhost:8080\" test"
}
Now, from your CLI:
npm run test:ci
The ci suffix mentions this process is fully automated
It's expected that you'll have to define CI=true for a real CI environment,
just as all CI tools do and it's not necessary for local usage.

JEST AND BABEL 7

I am using typeorm and I have created a test file (city.test.js) inside a entity folder src/entity/City/citi.test.js The test runs without problems when doing npm run test (which just runs jest), the problem is when I want to start the service so I can work with it.
My command is:
"serve": "nodemon ./src/index.js --ext js,graphql --ignore 'src/**/*.test.js' --exec babel-node"
but I get this result
Error: ReferenceError: test is not defined
And I suppose is my test file, it is not getting ignore, any idea what should I do. ?
Thank you.

NPM: How can I hook SET NODE_ENV in package.json's prestart script?

I have a basic App created using npm init -y. In package.json I have a main entry which points to server.js.
{
"name": "rest-api",
"version": "1.0.0",
"description": "",
"main": "server.js",
"private": true,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"prestart": "SET NODE_ENV=dev"
}
I am trying to set the NODE_ENV variable in prestart and let npm to call main to invoke npm start. But environment variable set in the prestart is not carry forwarded and is undefined. When I run 'npm start', console outputs that both commands are executed in order.
PS D:\test\RestAPI> npm start
> rest-api#1.0.0 prestart D:\test\RestAPI
> set NODE_ENV=dev
> rest-api#1.0.0 start D:\test\RestAPI
> node server.js
undefined
[undefined] Listening on http://localhost:3000
but when I print the variable from the app, it is undefined. Is there anything that I am doing wrong here, or is this how it is supposed to behave? Is there a way to invoke and set env variable using 'SET NODE_ENV=dev' without chaining it to 'node server.js'
When I combine both in the 'start' as below, then the environment variable is set.
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "set NODE_ENV=dev && node server.js"
}
I am testing this on Windows 10, npm version 3.10.10. Appreciate your help.
I know how this can be done in package.json using 'start'. This question is specific to how this can be achieved through 'prestart'.
Thanks.
The short answer is NOT possible.
1. Why :
this is not be possible because each script executed by different processes that npm spawns for this purpose which has its own environment variables.
To realise that, create test project and configure both scripts to be like
"start": "pause&&set VAR1",
"prestart" : "pause&&set VAR1=value&&set VAR1&&pause",
On windows open the task manager and pay close attention how many cmd process es are listed before running the script.
run the command "npm start" and at each request "press any key to continue..." just notice how processes created are created. I attached screenshots for this in order
2. Unless :
you change how npm executes different scripts to use one cmd for all the scripts which I think is complicated and probably will create bugs.
If you want to chain scripts and add env variables along the way then checkout the example given in the cross-env package:
{
"scripts": {
"parentScript": "cross-env GREET=\"Joe\" npm run childScript",
"childScript": "cross-env-shell \"echo Hello $GREET\""
}
}

Resources