Running Jest from node in a CRA application with expose-gc - node.js

I'm having issues with memory leaks coming from running my test suites with Jest where memory usage keeps growing with each suite.
After searching through the net, I've found that this could be related to a garbage-collector behaviour, and multiple Github threads suggest running this command:
node --expose-gc ./node_modules/jest/bin/jest.js --coverage --runInBand --logHeapUsage
The issue is that my project uses React (with CRA not ejected) and Typescript, so whenever I run this script it throws a Syntax error because of Typescript.
I've tried installing ts-jest library but it does not work. It may be related, but running the ts-jest setup init complains about already having a configuration due to CRA.
I've been searching and I have not found anything, since all related threads are about the known memory leaks Jest has, but none explain how to execute the node command with the expose-gc in a project with React and Typescript.
Is there any way I can expose the GC to the Jest script used by CRA so I can keep using the same configuration as until now?
Otherwise, how can I execute the node --expose-gc jest parsing my files so that it does not throw an error?
I'd also need to use the --inspect-brk to see where the leak comes from, so even if the --detect-leaks works, I still need to find a way to execute my Jest config from node command.
Thank you!

After reviewing the documentation from Jest, I've seen this section which suggests to run the debug configuration in VS Code calling react-scripts. After playing a little bit with it, this is the command that got it working:
node --inspect-brk node_modules/react-scripts/scripts/test.js --no-cache --env=jsdom --runInBand
As you can see, you have to call the test.js file inside react-scripts directly, and then you can send all the arguments you want to Jest, as you'd normally do when running tests directly from the terminal of your project.
If you execute this script:
node --inspect-brk node_modules/react-scripts/bin/react-scripts.js test --no-cache --env=jsdom --runInBand
You will be able to attach to the node debugger, but you won't be able to set debugger stops in your test files, as it will attach to the main process, which is react-scripts (and not the test script itself).
Hope this might help someone in a future!

Related

Run E2E tests in IDE or command line

I'm using Stencil.js to create a web component library and I'm heavily relying on E2E tests. As they're rather slow it becomes more and more cumbersome to run the entire test suite (using the Stencil.js CLI) while developing new components.
However, I'm not able to run single tests in my IDE (IntelliJ IDEA) or via command line. It works perfectly fine for unit tests though.
My Jest config looks like this:
module.exports = {
"roots": [
"<rootDir>/src"
],
"preset": "#stencil/core/testing"
}
When I try to run tests in a single file (jest --config jest.config.js --testPathPattern src/components/button/button.e2e.ts$)
it fails, because
newE2EPage() is only available from E2E tests, and ran with the --e2e cmd line flag.
newE2EPage() comes with Stencil.js and I don't know what Stencil.js's CLI does in the background. Furthermore, I cloned the Stencil.js repository, just to see if it is working with their E2E tests (https://github.com/ionic-team/stencil/tree/master/test/end-to-end) but it doesn't work either.
Any idea how I can configure Jest so that it's able to run Stencil.js-E2E tests from the command line?
The --e2e flag is used for the npm script in the package.json. To start e2e tests, you can add this in your package.json:
"scripts": {
"test:e2e": "stencil test --e2e"
}
And run npm run test:e2e. For a specific file, you add it at the end like this:
npm run test:e2e src/components/button/button.e2e.ts
For more info, see the StencilJS doc: https://stenciljs.com/docs/end-to-end-testing
i have the same problem. IntelliJ and 'Run' single 'it' didnt work.
newE2EPage() is only available from E2E tests, and ran with the --e2e cmd line flag.
when i run 'npm run test' everything will work fine. the difference is that npm run stencil before and only jest dont work.
here is the stencil jest dir https://github.com/ionic-team/stencil/tree/master/src/testing/jest aswell a config.
i found in here https://stenciljs.com/docs/testing-overview a VS-CODE run jest code but no Intellij setup.
im on the run to get the path of the current file to run stencil via npm and the path the e2e file. but i cant find the correct variable for the run config.
i hope we got this solved soon.
cheers
I am not a VS Code user, but in contrast to IntelliJ there is a launch.json for VSC to run single tests: https://github.com/ionic-team/stencil-site/pull/480

How to debug Protractor e2e tests with ndb?

I have recently discovered the magic of debugging Node applications with ndb. (You should really check it out, if you've never seen it.)
For our non-e2e integration tests (which use jasmine) I was easily able to debug the test code simply by substituting ndb for node.
ndb node_modules/jasmine/bin/jasmine.js --config=jasmine.json
When I do the same for protractor, the debugger comes up, but the tests don't begin. For example, the following fails:
ndb node_modules/protractor/bin/protractor protractor.conf.ts --suite smoke
Any clues? (I have a suspicion that it has to do with the Typescript transpilation that happens, but I have no evidence hard evidence.)
I solved my own problem by more trial-and-error. I do not understand why this makes a difference, but the following variation on the ndb command worked:
ndb node node_modules/protractor/bin/protractor protractor.conf.ts --suite smoke
According to ndb --help, ndb provides several variations on how to kick off debug sessions. Like I said, I'm not sure why the ndb node flavor worked while straight ndb failed.

Waiting for webpack bundling before launching nodemon

I have a nodejs project written in Typescript. Therefore, i have webpack using a typescript loader that transpiles my code in Javascript and bundles it in a server.js file (in a dist folder)
When in developement conditions, my webpack runs with its watcher ON and so does nodemon.
Problem is, when i launch my script for the first time combining webpack and nodemon, since webpack is in watch mode it doesn't have an exit code saying that everything is ok, nodemon script can be started. If i run them simultaneously, nodemon will launch faster than webpack and since server.js file doesn't yet exist, it will crash at the start.
I want to launch thanks to one single command both scripts but make nodemon command wait for the bundling to be done.
First of all, when please provide some code when submitting questions.
and since server.js file doesn't yet exist
I think you should work around your setup a little bit s.t. webpack doesn't create your server.js file if you want to do this.
Basically you can chain multiple commands in a script like so webpack -d && nodemon index.js. This will launch node after webpack completes. However if you setup webpack in watch mode -w it never exists, so you can't chain another command to it. So webpack -d -w && nodemon index.js never gets to the nodemon part.
A solution to the above is to chain them using only &, which I guess you are doing, but in this way they both start at the same time. Hence, if you make your setup independent (webpack doesn't interfere with nodemon starting script) you can list them like so.
If for whatever reasons you can't do this or don't want to, your only option is with 2 separate scripts that you launch manually one after the other.
If I were you, I would just use nodemon-webpack-plugin:
Uses Nodemon to watch and restart your module's output file, but only
when webpack is in watch mode (ie, --watch).
Saves the need for installing, configuring and running Nodemon as a
seperate process.

`npm test` never exits

I use mocha to run my unit tests, and often use npm test in order to run it. My package.json contains these script definitions:
"pretest": "NODE_ENV=test node migrate all",
"test": "DEBUG= NODE_ENV=test mocha --recursive",
If I run either one of these commands directly in my shell (i.e. not going through npm) they execute fine (790 tests takes about 2m to run, the migration script is done in under 1s). The processes also exit cleanly.
If, however, I run these via npm test, everything runs in exactly the same way but the process doesn't exit (I have to manually cancel it with ^c).
I can't work out how to debug exactly what is going on here in order to work out why the process isn't exiting.
It's worth noting that if I test a subdirectory (npm test ./test/queue) which does not interact at all with the database, then the process exits fine. These tests do, however, interact with an AMQP broker so there is some activity over sockets. This suggests to me that the database connection is causing the problem. I am using knex to connect to a postgres9.6 server. This also suggests that the pretest script is not the problem. If I try to run a suite of tests which do interact with the database, the process never exits (so presumably the open sockets are preventing it from doing so, but why this should only happen in the case of npm test rather than direct execution is beyond me).
Extra info:
node version: 8.7.0
mocha version: 4.0.1
npm version: 5.6.0
knex version: 0.14.0
I am using async/await in my codebase
I was mistaken in thinking this to be an npm problem. Rather, when I was running mocha in my shell it was using the globally installed mocha, which is of a different version to the locally installed one. Running with this version causes the same hanging issue.
This change in behaviour appears to be coming from this issue, which is described thus in the changelog:
By default, Mocha will no longer force the process to exit once all tests complete. This means any test code (or code under test) which would normally prevent node from exiting will do so when run in Mocha. Supply the --exit flag to revert to pre-v4.0.0 behavior (#ScottFreeCode, #boneskull)

Log to node console or debug during webpack build

What is the best practice for debugging during webpack build process? Any console.log in the entry script doesnt output to node console.
As of the current version of webpack (September 2019), if you do a build instead of launch a dev server, console.log will output to std out (i.e. the node console).
Just make sure you are doing a full build (i.e. "npm run build") instead of a dev server (i.e. "npm run dev").
The dev server disables console.logs during the compile process in many circumstances, and/or the way the progress bar updates, the console.log strings are overwritten so you never see them.

Resources