Debug Mocha tests being executed via NPM in terminal of VSCode - node.js

Does anyone know how to configure VSCode to debug Mocha tests when executing via a test script? Setup is:
"test" config in package.json of project specifying the mocha command to execute( mocha -R mochawesome -s 3000 -t 30000 ./index.js )
'npm test' command used in internal terminal of VSCode with '-g' param to allow for execution of specific descriptions within CoffeeScript test files
I want to be able to debug the execution of these individual tests(i.e. run 'npm test -- -g "test description"' in VSCode and break in VSCode's Debug view when it reaches a bp). Is this possible? Would an 'attach' config be needed instead of 'launch'?
I've tried the standard debug configs provided in VSCode , and tried to modify them based on info found in various places, but no success so far. Any help would be great, not too familiar with the IDE, or any of these processes Thanks!

Late answer but it may help people falling on this question.
Adding inspect-brk will hold the process until you connect your debugger, vscode in this case. After that tests will run and stop on your debug points. Usually the listening port for debugging is 9229, but you'll see the correct port on the sysout.
mocha --inspect-brk test.js
Credits to Run node inspector with mocha

You can attach vs code debugger to a process launched by script
For that you need to:
1) Add mocha's --inspect option to your script
2) Configure your launch.json this way
"configurations": [
{
"type": "node",
"request": "attach",
"name": "Mocha: tests",
"processId": "${command:PickProcess}",
"restart": true,
"protocol": "inspector",
},
]
3) After running your script hit F5 and pick mocha's process from vs code popped up processes list (you need to be quick here :) )
4) Second time you run the script and hit F5 vs code will automatically pick the right process for you

Related

Vscode debugger - auto-attach when process restarts through pm2

I am experimenting with different environments for debugging a nodejs application. I am running this application using pm2, with the --watch flag, so that my application restarts when files are changed / saved. Relevant scripts are these:
"start": "node --inspect -r tsconfig-paths/register -r ts-node/register ./src/server.ts",
"launch": "pm2 start pm2.config.js",
And my pm2.config.js looks like this:
module.exports = {
apps: [
{
name: 'myapp',
script: 'npm',
args: 'start',
watch: ['src'],
},
],
};
So far, I have been doing debugging in the chrome node inspector. I'm also using the chrome extension NodeJS Inspector Manager, which is a nice wrapper for the node inspector. It has a nice UI, and you can see there are options for Auto Attach and Auto Resume:
With these enabled, any time I save files in my project, pm2 will restart the application. NiMs automatically detaches and reattaches to the running application, and I have an interactive chrome inspector debugging environment that refreshes through application restart.
I'd like to reproduce this effect within the vscode debugger. I can manually start a debug session that attaches to my application running through pm2. With some help from Debugging With PM2 And Vscode, I'm able to direct the vscode debugger to attach to my application running through pm2. However, when I save files, pm2 restarts the process, and vscode debugger detaches, but does not reattach.
NiMs has a vscode extension, though it doesn't seem to offer the same functionality within vscode as within chrome, as far as I can tell.
Is there a way to set up a vscode debugger to attach to a pm2 process, and automatically restart as the process restarts (on the same debugger port)?
To have vscode debugger re-attach automatically, you can add the flag restart to your configuration:
{
"name": "Attach to node",
"type": "node",
"request": "attach",
"restart": true,
"port": 9229
}
source: https://code.visualstudio.com/docs/nodejs/nodejs-debugging#_restarting-debug-sessions-automatically-when-source-is-edited

VSCode NodeJs: Debugger not stopping at breakpoint (WSL2/Ubuntu18)

Using WSL2/Ubuntu18 I've not been able to make the VSCode NodeJs Debugger to stop on the breakpoints of any NodeJs app. When I start the debugger, it runs (I can see the output on the integrated terminal) but breakpoints are simply ignored.
The simple.js file, with a breakpoint on line 3:
The launch.json is set to:
{
"version": "0.2.0",
"configurations": [
{
"name": "NodeJs: Launch Program",
"program": "${file}",
"request": "launch",
"skipFiles": [
"<node_internals>/**"
],
"type": "pwa-node",
"console": "integratedTerminal"
}
]
}
When I press F5 or click on the "Start Debugging" button on VS Code, the app runs and following appears on the integrated Terminal:
/usr/bin/env 'NODE_OPTIONS=--require /home/myuser/.vscode-server/bin/ea3859d4ba2f3e577a159bc91e3074c5d85c0523/extensions/ms-vscode.js-debug/src/bootloader.bundle.js --inspect-publish-uid=http' 'VSCODE_INSPECTOR_OPTIONS={"inspectorIpc":"/tmp/node-cdp.19338-1.sock","deferredMode":false,"waitForDebugger":"","execPath":"/home/myuser/.nvm/versions/node/v14.15.1/bin/node","onlyEntrypoint":false,"autoAttachMode":"always","fileCallback":"/tmp/node-debug-callback-ff32d873905abafa"}' /home/myuser/.nvm/versions/node/v14.15.1/bin/node ./simple.js
Debugger attached.
0
1
2
3
4
Waiting for the debugger to disconnect...
I've already upgraded from Node10 to Node14, but the problem persists.
On another computer using WSL1, and using the same launch.json the debugger stops at the given breakpoints. Do I need to set something additionally on WSL2? For the record, this is what appears on the integrated terminal on the WSL1 computer before it stops at line 3:
/usr/bin/env 'NODE_OPTIONS=--require /home/myuser/.vscode-server/bin/ea3859d4ba2f3e577a159bc91e3074c5d85c0523/extensions/ms-vscode.js-debug/src/bootloader.bundle.js --inspect-publish-uid=http' 'VSCODE_INSPECTOR_OPTIONS={"inspectorIpc":"/tmp/node-cdp.787-3.sock","deferredMode":false,"waitForDebugger":"","execPath":"/home/myuser/.nvm/versions/node/v14.15.1/bin/node","onlyEntrypoint":false,"autoAttachMode":"always","fileCallback":"/tmp/node-debug-callback-b901b6d6e3e9799b"}' /home/myuser/.nvm/versions/node/v14.15.1/bin/node ./simple.js
Debugger attached.
<Breakpoint hit and stop...>
Additional info, debugging Python3 files work correctly on both machines.
Both computers have the same VS Code Version installed.
Update:
You can follow the issue on GitHub: https://github.com/microsoft/vscode/issues/113283
The problem is that the NodeJs App is being run from a symlinked address - so the debugger can not handle it.
Answer from one of the developers of VSCode/NodeJS on github:
It looks like you have your script symlinked into /bin/nhosko/simple.js, but its actual location is /mnt/c/Users//bin-nhosko/simple.js. In this case you need to specify some flags so that Node will report the linked location that vscode sees and told the debugger about: https://code.visualstudio.com/docs/nodejs/nodejs-debugging#_can-i-debug-if-im-using-symlinks. I want to make the debugger smart enough to fix this automatically in microsoft/vscode-js-debug#776.
https://github.com/microsoft/vscode/issues/113283#issuecomment-750371948

How to debug "built" production NodeJS

I am using Visual Studio code to debug a node application in production environment
The Node process runs inside docker,
I port-forwarded and signaled USR1 to enable attaching debugger from VS code to that node process
My VS Code configuration is like this
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "attach",
"name": "Debug: service",
"sourceMaps": true,
"smartStep": true,
"remoteRoot": "/src/",
"localRoot": "/home/my-username/work/orders/src/",
"protocol": "inspector",
"port": 9229,
"restart": true,
"address": "0.0.0.0",
"skipFiles": [
"<node_internals>/**",
"<node_modules>/**"
]
}
]
}
From VS code, I can hook into the application and the application can break on exception
However there is no source-mapping which cause all my breakpoint in my source-code to be "unbound breakpoint"
The loaded script list in VS code show that
The VS code debugger is able to see the node_modules and the built version of my source code inside dist. One other notable point is that the source code that is used to build the /dist is also available directly in the production server, in the upper folder.
How can I debug the built production process, using my unbuilt source code in this case?
I added Chrome behaviour as separate question
NodeJs: Chrome inspector can map source but unable to debug on original source
I don't know whether it will be helpful to you or not. But I think you have to use node-inspector. It can be used from any browser supporting WebSocket. It is really good.
Cool stuff
Node Inspector uses WebSockets, so no polling for breaks.
Remote debugging and debugging remote machine.
Live edit of running code, optionally persisting changes back to the file-system.
Set breakpoints in files that are not loaded into V8 yet - useful for debugging module loading/initialization.
Embeddable in other applications - see Embedding HOWTO for more details.
Node already ships with an integrated debugger. However, it doesn’t have a GUI, so you need to use the command line version.
You can launch this debugger using node debug.
$node debug test.js
< Debugger listening on port 5858
debug> . ok
break in test.js:1
> 1 var a= 5;
2 a = a*a
3 a += 2;
debug>
It shows you where it’s paused and then lets you control execution with commands like next and cont.
debug> next
break in test.js:2
1 var a= 5;
> 2 a = a*a
3 a += 2;
4
The repl and watch commands allow you to see the values of local variables.

How to debug a Node.js server? The debugger skips my breakpoints! (Using VSCode)

I'm trying to debug a Next.js app with a custom server which I normally run with a dev Yarn script that executes node server.js.
VSCode includes a Node.js debugging extension and this guide, which I've followed. I created a new Yarn script called dev:debug that runs node --inspect server.js, and the following configuration in launch.json:
{
"type": "node",
"request": "launch",
"name": "Debug via Yarn",
"runtimeExecutable": "yarn",
"runtimeArgs": ["dev:debug"],
"port": 9229
}
However some breakpoints in modules imported by server.js are skipped and I'm not sure why. Other breakpoints in Next components do work when I load pages in my web app. Any ideas?
OK! Here's what's happening (and I'm posting all this to SO because I couldn't find the answer online):
When you build a Next.js app, you're writing BOTH the server app (node), AND the server-side web app (next), which are separate things! Additionally, you're also building a client-side app (React) on top of that. (If you're used to other platforms like PHP or Python web apps that use servers like the built-in ones, Apache, or NginX, this isn't obvious!)
Running node --inspect server.js tells the debugger to load the server and THEN start debugging your web app ONLY ("user code").
Solution: node CLI has a special --inspect-brk option to use when you also want to debug the code of the server itself! Yep, the solution is 4 more characters (-brk).

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