New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Debugger Won't hit breakpoints in jest test #60187

Closed
jacksaunders opened this Issue Oct 8, 2018 · 27 comments

Comments

Projects
None yet
@jacksaunders
Copy link

jacksaunders commented Oct 8, 2018

When running Jest tests, I am unable to set breakpoints in the *.test.js / *.spec.js files. When i set a breakpoint in a location and start the launch.json config the breakpoints move around.

I am unable to provide access to my repo so i have created a repo which is close to what i am working on, its an ejected create react app and can be seen here.

https://github.com/jacksaunders/vscode-jest-test

I ran vscode with all extensions disabled, and just ran the basic App test that comes with create react app.

here is a quick gif of what is happening

46548699-b4abb880-c8c7-11e8-9564-0f99cb23e4e9

vscode version info

46548737-d016c380-c8c7-11e8-8813-71ab9d711575

@vscodebot

This comment has been minimized.

Copy link

vscodebot bot commented Oct 8, 2018

(Experimental duplicate detection)
Thanks for submitting this issue. Please also check if it is already covered by an existing one, like:

@isidorn isidorn assigned roblourens and unassigned isidorn Oct 9, 2018

@isidorn isidorn added the debug label Oct 9, 2018

@roblourens

This comment has been minimized.

Copy link
Member

roblourens commented Oct 9, 2018

In your webpack config, could you try changing devtool to source-map? The other modes sometimes don't provide enough info for accurate sourcemapping.

@roblourens

This comment has been minimized.

Copy link
Member

roblourens commented Oct 10, 2018

Actually there is some discussion going on about the same issue in facebook/create-react-app#5319

@roblourens roblourens added the bug label Oct 10, 2018

@roblourens

This comment has been minimized.

Copy link
Member

roblourens commented Oct 10, 2018

I am going to keep this issue open to figure out a better workaround on vscode's end.

Pasting my response from the other issue:


tl;dr: a workaround is that breakpoints set after launching work.

I can repro this, I tried downgrading jest in the test repo, but it doesn't make a difference for me? Could one of you share a test repo where it does work with jest downgraded? Or if it's easier just set "trace": true in your launch config, run it again, and share the log file.

Here's the problem: In a transpiling scenario you can use the outFiles parameter to point vscode towards the output sourcemaps so it can preload them and resolve your breakpoints to their real locations. But in this scenario, the sourcemaps are generated in memory and don't exist on disk.

So you set a breakpoint in a .js file. VS Code doesn't know whether it's a bp in a script with no sourcemaps, or a transpiled script that will have sourcemaps at runtime. Since it's a .js file, we guess and set breakpoints for that path and line. Anyone using .ts or something else won't see an issue.

Then, jest loads the transpiled script and gives it the same path as the file on disk. It's a match, and your breakpoint hits. But the line numbers don't match between the two scripts, so you've stopped on the wrong line. At the same time, vscode has loaded the sourcemap so any breakpoints you set at this point will bind correctly.

If this is really new in Jest then they might have changed how they name the loaded scripts. If they can name them differently from the source files on disk, that would fix this. Maybe we should provide an option to disable this optimistic bp placement but it should "just work"...

But this scenario where sourcemaps can't be preloaded from disk has always been imperfect in vscode. We would still have a race to load the sourcemap and set the BP before the line of code with the BP executes. Chrome gives us a way to break every time a script loads, giving us a chance to catch up and load sourcemaps. Node doesn't support that unfortunately. We've experimented with guessing the name of the script at runtime, setting a BP for line 1, then checking whether it has sourcemaps. That would help in this scenario but is complex and relies on the name of the script at runtime matching the path on disk.


One possibility is that we adapt "breakOnLoad": "regex" from chrome-debug to help with this scenario.

@SimenB

This comment has been minimized.

Copy link

SimenB commented Oct 30, 2018

Hey, Jest maintainer here 👋 We do write the source map to disk (as well as keep it inline in the sourcecode of the file, https://github.com/facebook/jest/blob/714cb516944c74a9ed9d6eda867911b398003468/packages/jest-runtime/src/script_transformer.js#L272). I'm not sure if it's possible to tell vs code where it is, though?

@roblourens

This comment has been minimized.

Copy link
Member

roblourens commented Oct 30, 2018

Oh that's interesting, where is that path?

@SimenB

This comment has been minimized.

Copy link

SimenB commented Oct 30, 2018

It is in /tmp somewhere (or your OS-dependent version of it). We get it by doing this and appending .map: https://github.com/facebook/jest/blob/714cb516944c74a9ed9d6eda867911b398003468/packages/jest-runtime/src/script_transformer.js#L109-L132
We do that for every single file transpiled by Jest.

We write it to disk for caching purposes, but maybe you can use it?

Is this something https://github.com/jest-community/vscode-jest can help solve?

@hbenl

This comment has been minimized.

Copy link

hbenl commented Nov 5, 2018

@roblourens I would very much like to have breakOnLoad for node debugging. I'm currently facing an issue where breakpoints aren't hit when debugging mocha tests in a docker container. When I insert a debugger; statement in the test, the debugger breaks at that statement and after that, breakpoints start working - so I guess this is the same timing issue that breakOnLoad was designed to fix.

@roblourens

This comment has been minimized.

Copy link
Member

roblourens commented Nov 9, 2018

Hey @SimenB I can't locate the cache on my disk, and I can't tell whether that code is running for sure. Does this happen all the time by default or is there an option I have to set to enable it?

I can't tell where config.cacheDirectory comes from?

@roblourens

This comment has been minimized.

Copy link
Member

roblourens commented Nov 9, 2018

Ah I did find it, never mind. But, since those files won't exist before we start running, this can't help us. Also since it's in a directory with random name, we won't know where to look for it. It does look like we can set the path by providing a config file.

it would help if there's a command I can run that would write out the cache without running the tests. Then I can run that, preload the sourcemaps, then start debugging. Does something like that exist?

@SimenB

This comment has been minimized.

Copy link

SimenB commented Nov 9, 2018

Running jest --config will list cacheDirectory, does that help? I don't think we have a way of pre-transpiling as we do it JIT - we don't analyze the dep graph to figure out what to transpile or transpile whole directories

@roblourens

This comment has been minimized.

Copy link
Member

roblourens commented Nov 9, 2018

Ok, I'm just not sure what to do about this then. When people use chrome devtools to debug, do they just rely on debugger statements all the time?

@SimenB

This comment has been minimized.

Copy link

SimenB commented Nov 9, 2018

In chrome, you can't set breakpoints before a file is loaded, at which point the sourcemap is available. So it doesn't "guess" if I understand what you currently do correctly.

Would it help if Jest exposed some jest --compileFile /path --compileFile /other/path?

@roblourens

This comment has been minimized.

Copy link
Member

roblourens commented Nov 13, 2018

Would that transpile the file on demand? I guess that would help but it would be simpler if there was one command to transpile the full project to a predictable location.

Ideally we could prepare the project with a preLaunchTask in the vscode launch config, then load the sourcemaps using outFiles.

roblourens added a commit to Microsoft/vscode-node-debug2 that referenced this issue Nov 13, 2018

@roblourens

This comment has been minimized.

Copy link
Member

roblourens commented Nov 13, 2018

I added a flag that will make this work a little better. In the next Insiders build you can set "_disableOptimisticBPs": true to prevent vscode from setting breakpoints until a sourcemap has loaded for the script. This will mean that breakpoints will only bind to the correct line, but they probably won't bind before the test actually runs. So you can add a debugger statement to the top of the file to give it some time to load the sourcemap, or rerun the tests in the terminal.

Anyone watching this thread, I'd appreciate if you try it out in tomorrow's Insiders build. It's not a permanent solution but should unblock this at least.

@roblourens

This comment has been minimized.

Copy link
Member

roblourens commented Nov 13, 2018

I'm still not clear on the workflow for debugging with chrome devtools. If people are used to adding debugger statements everywhere, then this isn't that bad.

Really what we need is a way to pause when a script is loaded. Chrome gives us this, Node does not.

Maybe an option to have Babel insert a debugger statement into each test would be helpful.

@CNSKnight

This comment has been minimized.

Copy link

CNSKnight commented Nov 15, 2018

  • don't know how to set a "flag"?

(Settings in 1.30.0-insider doesn't seem to have _disableOpitimisticBPs)

@roblourens

This comment has been minimized.

Copy link
Member

roblourens commented Nov 15, 2018

In your launch config (it will be underlined as unrecognized, it's undocumented)

@roblourens

This comment has been minimized.

Copy link
Member

roblourens commented Nov 20, 2018

Has anyone tried this out? Can you comment on whether you it helps, and how the experience compares to using chrome devtools? Need to decide whether to make this part of the official recommended and documented workflow.

@jacksaunders

This comment has been minimized.

Copy link

jacksaunders commented Nov 21, 2018

Hey @roblourens , just tried this out and can confirm that it from my initial tests it is working perfectly, its stopping at the right breakpoints both in the .spec.js files as well as the .js files themselves, i didn't need a debugger statement.

I will continue to use the insiders build and will update this thread with any issues if they arrive but so far so good 😀

Thanks for the hard work on this, really helped me out.

@roblourens

This comment has been minimized.

Copy link
Member

roblourens commented Nov 21, 2018

That's great, thanks for reporting back.

@roblourens roblourens added this to the November 2018 milestone Dec 4, 2018

@roblourens roblourens closed this Dec 4, 2018

@roblourens

This comment has been minimized.

Copy link
Member

roblourens commented Dec 4, 2018

Verification steps

  • Use create-react-app to create a basic app (don't use the --typescript option)
  • Use this launch config for tests:
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Debug Jest Tests",
      "type": "node",
      "request": "launch",
      "disableOptimisticBPs": true,
      "runtimeArgs": [
        "--inspect-brk",
        "${workspaceRoot}/node_modules/.bin/jest",
        "--runInBand"
      ],
      "console": "integratedTerminal",
      "internalConsoleOptions": "neverOpen",
      "port": 9229
    }
  ]
}
  • Set breakpoints in a .test.js file
  • Verify that they don't shift around and can be hit
  • Note that they may not be hit on the first run. Rerun the tests from the terminal (in the same debug session) or put a debugger statement at the top of the file. #60187 (comment)
@alexr00

This comment has been minimized.

Copy link
Member

alexr00 commented Dec 6, 2018

I tried the verification steps by cloning the create-react-app repo, following the instructions to create an app, and then setting up the launch.json but I get an error when I try to debug:
Debugger listening on ws://127.0.0.1:9229/cf66348c-051e-42cf-b1c2-a5670d65599c
For help see https://nodejs.org/en/docs/inspector
Debugger attached.
C:\Users\create-react-app\test-app\node_modules.bin\jest:2
basedir=$(dirname "$(echo "$0" | sed -e 's,\,/,g')")
^^^^^^^

SyntaxError: missing ) after argument list
at createScript (vm.js:80:10)
at Object.runInThisContext (vm.js:139:10)
at Module._compile (module.js:616:28)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)
at Function.Module._load (module.js:497:3)
at Function.Module.runMain (module.js:693:10)
at startup (bootstrap_node.js:191:16)
at bootstrap_node.js:612:3
Waiting for the debugger to disconnect...

@weinand

This comment has been minimized.

Copy link
Member

weinand commented Dec 6, 2018

@alexr00 it looks like you are running a linux/macOS shell script instead of a Windows script.

Does it make a difference if you add a windows specific path to the launch config, like this:

      "windows": {
        "program": "${workspaceFolder}/node_modules/jest/bin/jest",
      }

(I'm trying to follow the recipe here: https://github.com/Microsoft/vscode-recipes/tree/master/debugging-jest-tests)

@roblourens

This comment has been minimized.

Copy link
Member

roblourens commented Dec 6, 2018

So I don't understand why node_modules/.bin/jest is actually a different file for me on mac vs windows, using a fresh create-react-app from the same version. On Mac it's a .js file and on Windows it's a shell script, and there is a .cmd next to it. That launch config is the recommended one from the jest docs. But yeah, the different path on windows is necessary, thanks. I think that same one would work on either windows or mac.

Also I updated disableOptimisticBPs to remove the underscore, make sure you update the config if you copied it earlier.

@Yerkon

This comment has been minimized.

Copy link

Yerkon commented Dec 21, 2018

@roblourens , thanks! Now breakpoints hits in correct places with using flag disableOptimisticBPs on Windows 👍

@JonathanAaron

This comment has been minimized.

Copy link

JonathanAaron commented Dec 28, 2018

I also had to set my node-version to something more current. "runtimeVersion": "8.12.0", But everything above worked great.

@vscodebot vscodebot bot locked and limited conversation to collaborators Jan 18, 2019

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.