How do I use node debug cli with Jest? - node.js

How can I just use the simple node cli/repl debugger with Jest?
The Jest documentation uses node-inspector, but it is outdated/deprecated as of Node 6.3. I tried the recommended command anyway on Node 7.7.4:
node --debug-brk ./node_modules/.bin/jest --runInBand --no-cache [your_test_file]
But this simply hangs on the following (assumedly waiting on node-inspector):
(node:13452) DeprecationWarning: node --debug is deprecated. Please use node --inspect instead. Debugger listening on 127.0.0.1:5858
I added --inspect as specified by the warning, but even then execution doesn't stop on my debugger statement in Chrome DevTools.
This seems overly complicated for a very simple use case.

I found the following command works:
node debug ./node_modules/.bin/jest --runInBand --no-cache [your_test_file]
...but with some quirky behavior. When the debugger first stops you will see:
break in node_modules/jest/bin/jest.js:10
8 */
9
>10 'use strict';
11
12 require('jest-cli/bin/jest');
debug>
Apparently Jest always injects this breakpoint so that you have time to open Chrome DevTools (irrelevant in our case since we're only going to use cli/repl).
Continue past this breakpoint with c, and after a short time (without any indication of course that things are progressing along) you should see your breakpoint:
break in webpack/assets/react/components/presentation/Feed/Comments/Comment/commentSpec.jsx:12
10 var wrapper = (0, _enzyme.shallow)(_react2.default.createElement(_comment2.default, { loading: true }));
11
>12 debugger;
13 expect(wrapper.find(_button2.default)).to.have.length(1);
14 });
debug>
The last weird thing is you need to type repl to inspect objects as described in Node Debugger and Inspecting variables using node's built-in debugger?
The combination of all these steps was not immediately obvious to me while reading the documentation, so I hope this answer helps someone get over the hurdle faster.

From node v8.4 the debugger keyword within the code is fixed for VM context. Refer this git comment.
1.Type debugger keyword in your Jest code:
describe('Testcase definition', () => {
it('should be defined with subobjects', () => {
debugger; // <-- This keyword breaks on Chrome inspect
expect(true).toBe(true);
});
});
Command to Run:
node --inspect-brk --inspect ./node_modules/.bin/jest -i tests/mytest.test.js
Now open chrome://inspect/#devices on Chrome. Voila!

Related

Retain Node.js debug mode when starting another process

To debug a Node.js process, I use:
node --inspect-brk foo_bar.js
But what if that instance would start another, separate instance, and this one would be - how to run that instance in debug mode as well?
The problem is, I am using the commander.js library for Node.js, like so:
var program = require('commander')
...
program.parse(process.argv)
This creates another instance of Node.js process, and hence I lose the debug functionality (I am debugging via Chromium browser). How can I overcome this?
Note: Commander only creates another process if you implement the subcommand using a stand-alone executable.
Commander detects debugger options being passed to the node invocation, and passes them to the subprocess with the debugging port incremented by 1.
e.g.
// index.js
const { program } = require('commander');
program
.command('sub', 'stand-alone');
console.log('1');
console.log('2');
program.parse();
// index-sub.js
console.log('3');
console.log('4');
% node --inspect-brk index.js sub
Debugger listening on ws://127.0.0.1:9229/25005682-6bf4-44fb-bdb2-2cc7749bb328
For help, see: https://nodejs.org/en/docs/inspector
Debugger attached.
1
2
Debugger listening on ws://127.0.0.1:9230/00d1924a-3122-4bef-86f2-65d562fbf3ed
For help, see: https://nodejs.org/en/docs/inspector
Debugger attached.
3
4

Is it possible to debug node js code that runs before the debugger attaches?

Using the instructions found here I have setup Visual Studio Code to debug my nodejs code.
But it takes the debugger a few seconds to attach to node. And during that few seconds the code just runs.
So a file like this, with a breakpoint on line 1:
• 1 console.log('')
Will never break because it quits before the debugger attaches.
I can quickly ^c the code then restart and sometimes catch the debugger but this is unreliable.
Is there an event I can wait for in my code so that I know the debugger is attached and it is safe to continue?
Or is there a better configuration for doing this?
Yes, using the --inspect-brk option for node instead of --inspect.
so when running your code it would look something like this
node --inspect-brk server.js

What are the steps to follow to debug memory leak in Jest?

My tests in Jest seem to be leaking :
What are the recommanded steps to debug that kind of issue?
I'm new to that kind of problem. As you can see, I have tried passing in the options documented in Jest (--forceExit --detectOpenHandles --runInBand --logHeapUsage), but that does not solve my problem.
I ran into that I needed to debug some tests leaking memory and found that taking a Heapdump of the process running the tests was trickier than expected. If you add the --inspect flag the cli command it will only inspect the jest process.
In order to attach a debugger to your test executer go into node_modules/jest_worker/build/worker.js and add the --inspect flag to the worker. Jest usually strip the --inspect flag.
Use this code:
_initialize() {
const args = process.execArgv.filter(v => !/^--(debug|inspect)/.test(v));
args.push('--inspect');
const child = (_child_process || _load_child_process()).default.fork(
require.resolve('./child'),
// $FlowFixMe: Flow does not work well with Object.assign.
Object.assign(
{
cwd: process.cwd(),
env: Object.assign({}, process.env, {
JEST_WORKER_ID: this._options.workerId,
}),
// Suppress --debug / --inspect flags while preserving others (like --harmony).
execArgv: args,
silent: true,
},
this._options.forkOptions,
),
);
...
}
Finally run your tests like this:
node --expose-gc scripts/test.js --env=jsdom --runInBand --logHeapUsage
If you have not ejected your react-scripts you may have to do that first, the change can be reverted after you're done debugging. --runInBand is important else you will get too many workers, jest creates one less worker than you have cores in your computer, so it will be hard to inspect / work with them.
Do not add the --inspect flag to the node --expose-gc scripts/test.js --env=jsdom --runInBand --logHeapUsage command since then the jest process will take the default debugger port.
After this step you run your tests and open Google Chrome, navigate to chrome://inspect/ your process will appear in the list of Remote Targets and from there you can do memory profiling and take heap dumps of your test process.

VSCode debugging not working for NodeJs application

I have added the configuration in the launch.json file with the following details :
{
"name": "Attach"
"type": "node",
// TCP/IP address. Default is "localhost".
"address": "localhost",
// Port to attach to.
"port": 5858
}
Now I start my app with the following command : node --debug-brk ./bin/www
When i go to VSCode and select Attach in the debugging menu on the top and click on the play button.
It attaches, but when i go to browser and open a page, it doesn't it the breakpoint or the handler function in my index.js file.
Can you please help what could be going wrong?
There are two issues with breakpoints in node (and these issues are not specific to VSCode but you can see them in node-inspector as well):
If you set breakpoints in your app's startup code and launch node with --debug (opposed to --debug-brk), node starts immediately and has executed your startup code before VSCode had a chance to register the breakpoints. So if you need to debug startup code use the --debug-brk flag because it allows VSCode to set breakpoints before node starts the application.
Node does not parse source files completely on load but delays parsing of closures (callbacks etc.) until their code is first hit. As a consequence breakpoints set on callbacks are not always correctly registered by node, because it does not have parsed the code yet. This 'lazy' behaviour can be disabled by starting node with the --nolazy flag.
In the next version of VSCode (0.4.0) we try to address these problem as follows:
VScode will always launch node with the --debug-brk flag but will hide the first stop and continue if the user did not specify "stopOnEntry: true". This will avoid problems with missed breakpoints in startup code.
If breakpoints are set in code that has not been parsed by node, node will register them at the next possible position in parsed code. Since these "actual" positions are returned by node to the client, VSCode is able to show these positions. So the user will see that a breakpoint set in an unparsed callback "jumps" to a position further down and he will better understand why the debugger is not stopping at the location requested. In addition we added a "Reapply" button to the breakpoint view which makes it really easy to clear and set all breakpoints.
Your breakpoints are probably set too early and are not registered by node. It should help if you set the breakpoints after you have attached.
We have improved this experience in VSCode and it should be available in 0.4.0
Always clear your breakpoints and set them after you attach. I learned the hard way. This is certainly a bug.
I've been digging into this and here is what I have found so far for 0.3.0.
This does not work!
In Code add a breakpoint to app.js or a route
In terminal run node --debug src/server/app.js
In Code attach the debugger
This works!
In terminal run node --debug src/server/app.js
In Code remove all breakpoints
In Code add a breakpoint to app.js or a route
In Code attach the debugger
This does not work, as --debug doesn't kick in unless its the arg after node and before the file
In terminal run node src/server/app.js --debug
In Code remove all breakpoints
In Code add a breakpoint to app.js or a route
In Code attach the debugger
This works, assuming you have a gulp process
In terminal run gulp serve-dev --debug
In Code remove all breakpoints
In Code add a breakpoint to app.js or a route
In Code attach the debugger
This does not work, sometimes
In terminal run gulp serve-dev --debug
In Code add a breakpoint to app.js or a route
In Code attach the debugger
Why sometimes? The best I can tell is that that the breakpoints sometimes get funky. Sometimes they work fine, and other times I have to remove them and re-add them before attaching the debugger.

How to disable in the node debugger "break on first line"

Is there a command line argument or an environment variable that disables the "break on first line" feature of the node debugger?
There are actually two debugger concepts in node: V8 debugger (with its TCP-based protocol) and a node command-line debugger (CLI).
When you run node debug app.js, a debugger CLI is run in the master node process and a new child node process is spawned for the debugged script (node --debug-brk app.js). The option --debug or --debug-brk is used to turn on V8 debugger in the child process.
The difference between --debug and --debug-brk is that the latter one adds a breakpoint on the first line, so that execution immediately stops there.
I would suggest you this solution:
When you are creating a child process from your webserver, run node --debug instead of node debug. This way there is only one child process created, it is running your application and it is not paused on the first line.
Now you can use any debugging tool that supports V8 debugger protocol - node built-in CLI debugger, node-inspector or you can event implement your own debugger front-end (GUI) if you like. (I presume this is what you are trying achieve by running CLI debugger in background?)
If you decided to use built-in CLI, just spawn another another child process and tell node CLI debugger to connect to the process started in step 1:
node debug localhost:5858
and continue as before.
According this issue I have opened in the node repo, currently, this is not possible. This is also something that the node guys don't see as a feature worth implementing "because it seems kind of pointless. […] Attaching to a running process does exactly" the same thing. See the rest of the discussion in the mentioned issue.
If you think you want such a feature, vote this up, leave a comment in the Github issue, and, if no response, open a new one and post it here as well.
Found this while looking for the answer myself - Seems that you can simply run
node-debug --debug-brk=0 (progname)
Hope this helps someone.
Write a chrome extension to click the start button
1. Run shell
mkdir run_as_devtools
cd run_as_devtools
touch manifest.json
touch run_as_devtools.js
2. Edit the files
run_as_devtools.js:
if (location.protocol === 'chrome-devtools:' && location.href.match(/ws=localhost/))(function () {
'use strict';
setTimeout(function () {
try {
document.querySelector('html /deep/ .long-click-glyph').click();
} catch (e) {
console.log(e);
}
}, 500);
})();
manifest.json: (it uses chromevox's key, so don't use it with chromevox)
{
"content_scripts": [{
"js": [ "run_as_devtools.js" ],
"matches": [ "<all_urls>" ]
}],
"key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDEGBi/oD7Yl/Y16w3+gee/95/EUpRZ2U6c+8orV5ei+3CRsBsoXI/DPGBauZ3rWQ47aQnfoG00sXigFdJA2NhNK9OgmRA2evnsRRbjYm2BG1twpaLsgQPPus3PyczbDCvhFu8k24wzFyEtxLrfxAGBseBPb9QrCz7B4k2QgxD/CwIDAQAB",
"manifest_version": 2,
"name": "Elevated Devtools extension",
"version": "1.0"
}
3. Install the extension
Chrome settings - More tools - Extensions- Developer mode - Load unpacked extension - select run_as_devtools folder
P.S. Better to use it with Node inspector manager https://stackoverflow.com/a/43018133/4831179
Reference: https://stackoverflow.com/a/17044405/4831179
I solved same issue just by switching from node v6 to v7
Similar to blackmiaool's idea but simpler, with node v8 you can start the script with --inspect. If you have the following code in it, when you open the debug window in Chrome devtools it will take you straight to the debugger point. Additionally this allows you to execute async code by hitting the "continue" button, which allows your code to run before returning you to the repl:
// app_shell.js
var UserModel = require("./some_user_model");
function looper() {
var Tmp = { UserModel: UserModel };
debugger;
setTimeout(looper, 100);
}
looper();
And in a shell script you can do something like:
echo "Click the 'Open dedicated DevTools for Node' link"
python -mwebbrowser about:inspect
node --inspect app_shell.js
See here for more info
This worked for me .
node --inspect index.js
If you haven't install inspector , install it as receommended by node docs:
npm install -g node-inspect

Resources