jasmine icon indicating copy to clipboard operation
jasmine copied to clipboard

Feature Request: Sourcemap support

Open nicosommi opened this issue 10 years ago • 49 comments

It would be nice if the original line number of the error is displayed when developing in coffeescript.

For example for this error: TypeError: entityCollection.get(...) is undefined in http://somehost:[someport]/somepath/SomeSpec.js (line 37)

It can be something like this (reading the sourcemap): TypeError: entityCollection.get(...) is undefined in http://somehost:[someport]/somepath/Spec.coffee (line 15) (and line 37 on /somepath/SomeSpec.js)

I think this can be done reading the //@sourceMappingURL or the //#sourceMappingURL attribute of the compiled js and later the sourcemap itself (using the value of that attribute), then there is the sourcemap interpretation using https://github.com/mozilla/source-map

nicosommi avatar Jan 02 '14 18:01 nicosommi

This code would belong in the reporters. The Jasmine team doesn't work in Coffee Script so we're not familiar with the pain points.

We'd be happy to look at a pull request that test-drove out this support for the HtmlReporter - and it should (naturally) support the spec and source files. Is this something you'd like to tackle?

infews avatar Jan 06 '14 22:01 infews

Yes just give me some time and I'll try to create a PR. Looking at the code I think that I need to modify the core/ExceptionFormatter.js around line 19. Im going to create a new js file and add the mozilla source-map dependency.

nicosommi avatar Jan 11 '14 13:01 nicosommi

I have the same issue, but from TypeScript. It's a bit of a pain to reverse-engineer the actual line numbers, esp. since IntelliJ does not make it all that easy to load the generated JS files. @nicosommi I'm curious what the status of PR is, as I might be interested in continuing work on it if you don't have the time.

Yona-Appletree avatar Mar 05 '14 21:03 Yona-Appletree

@Yona-Appletree yes, I've a simple (I mean really simple) example of an HTML loading a script, detecting the SourceMap, loading it and translating some line from the browser. There is still hard work to do: make it nicer and put it into the logic of jasmine. If you are interested I made a tar that you can download here http://ge.tt/6kj7GWP1/v/0?c It just proves that it can be done

nicosommi avatar Mar 08 '14 13:03 nicosommi

I feel this is probably out of scope of jasmine itself because it involves fetching and parsing sourcemaps.

I have pushed a module which does that part to https://github.com/novocaine/sourcemapped-stacktrace. I would like to integrate that with a Jasmine reporter, but I need an asynchronous hook for the reporter to do its work (as would any solution to the problem).

I have created a pull request for the hook in 6b7302f9da8fc34044a9d3431ac639b6e5a09f1a

Would also appreciate thoughts on whether a reporter that integrated sourcemapped-stacktrace is useful enough to go into jasmine source (and would only work if the developer had loaded sourcemapped-stacktrace) or whether that reporter in itself should be another module.

novocaine avatar Jul 19 '14 04:07 novocaine

@novocaine you're bringing up an interesting idea.

Maybe instead of a reporter concern (and your pull request #630), it's an ExceptionFormatter concern? That forces the question of how to expose this functionality so that projects could provide a map, or turn on something.

infews avatar Jul 22 '14 20:07 infews

@infews, thanks for taking a look at this.

Would you accept a patch to make the ExceptionFormatter something customizable through env, similar to how you can customise the reporter? Or is this possible already?

I am imagining there could be a formatter you opt into if you want to use sourcemapped stacktraces. I don't feel strongly about whether such a formatter lives within jasmine or not, just that there should be a way to do this without hacking jasmine.

Also thinking that maybe sourcemapped-stacktrace could provide a sync interface to solve the problems with integrating async into the chain.

novocaine avatar Aug 01 '14 10:08 novocaine

Ugh.

At the moment, the ExceptionFormatter is used in a factory that's defined in Env.js (see). We allow options to be passed into jasmine.getEnv() which is mostly used for testing.

So to make this happen, you'd have to be able to define the constructor of the formatter before the Env is created and pass it in during the boot.js process. You can't do that today without writing your own boot.js. Not awesome, but possible.

Do you want to play around with a PR for Env.js that allows the exception formatter to be passed in? I think we could take that and allow your formatter to work with a custom boot.js. And we could start a doc for all the improvements that need to happen at boot time for a Jasmine 3...

infews avatar Aug 27 '14 16:08 infews

I think in-line sourcemaps would be more appropiate for this situation, as you wouldn't have to worry about fetching a different file for the sourcemap.

Zequez avatar Dec 02 '14 00:12 Zequez

+1 this would be useful for running unit tests written in Typescript

alexeagle avatar Apr 24 '15 21:04 alexeagle

:+1: I compile all my tests beforehand using typescript. Source map support would be really nice. I hate digging through the generated file.

caseyhoward avatar Jun 12 '15 16:06 caseyhoward

+1 as someone using webpack, I have no idea where the actual errors are without source map support.

geddski avatar Aug 01 '15 20:08 geddski

For anyone else needing this, I've found that adding ?catch=false to the URL at least lets the errors make it to the console so the browser can use source maps to show you where the errors are.

geddski avatar Aug 01 '15 20:08 geddski

+1 to support tests in coffeescript In the meanwhile, @novocaine , do you have some tips on how to integrate your module in my project without patching Jasmine?

cmdelatorre avatar Oct 28 '15 14:10 cmdelatorre

sorry, you definitely have to patch Jasmine..

novocaine avatar Oct 28 '15 16:10 novocaine

@geddski I tried out, but it does not work, because the error was rethrown by jasmine, so it points to the code of jasmine instead of my source code. (Btw. did anybody manage to use sourcemaps in firefox and chrome. I got proper support only in opera and msie.)

If somebody needs this feature, it works with karma + browserify + jasmine (tested with phantomjs). Here is a project template: https://github.com/inf3rno/javascript-project-template

ghost avatar Nov 02 '15 20:11 ghost

If anyone else is looking for a quick hack to get the source mapped stack traces working with Jasmine's HTML reporter while this is being figured out, here's a gist for you: https://gist.github.com/guncha/f45ceef6d483c384290a

guncha avatar Dec 10 '15 20:12 guncha

thx @guncha

I am using it with karma jasmine html reporter and its working well! I haven't found another solution so I just can recommand that atm.

DanielSchuech avatar Jan 21 '16 09:01 DanielSchuech

I actually ended up using https://github.com/evanw/node-source-map-support which overwrites the native Error#stack to fetch the source maps and rewrite the stacktrace. It works with Jasmine as well as errors in the console. The only issue with testing is that is uses AJAX, so if you use jasmine-ajax, it will break in strange ways.

guncha avatar Jan 21 '16 15:01 guncha

@guncha Thanks for the gist, I hacked it a little to make it work but that'll do for now. Do you know if there is a way to restore the stack traces before they get sent to karma/testem/initial loader?

EDIT: nevermind, I figured a way to have them using node-source-map-support. It only works for Chrome but I guess that's good enough and much better than the previous solution.

ArnaudRinquin avatar Feb 03 '16 22:02 ArnaudRinquin

This issue still makes using jasmine such a major pain when using something like webpack. Not knowing what line errors are coming from makes things impossible.

geddski avatar Feb 04 '16 05:02 geddski

Is there a different JavaScript test runner that handles sourcemaps??

andyl avatar Feb 04 '16 23:02 andyl

As @infews mentioned, we'd be happy to review a pull request that either:

  • Allows injection of an ExceptionFormatter, allowing a custom one that can deal with sourcemaps
  • Allows injection of some sort of filtering/rewriting function that the existing ExceptionReporter can use to accomplish this

This would also allow for a better solution to #801 and filtering lines out of the stacktrace of an error.

slackersoft avatar Feb 23 '16 21:02 slackersoft

We have added very preliminary support for this similar to the way that has been described for gulp-jasmine-browser, it is currently only supported in the browser stacktrace, I haven't yet re-worked the headless reporter to support this correctly. You can check that out here: https://github.com/jasmine/gulp-jasmine-browser

Make sure you use the {sourcemappedStacktrace: true} as the option to the spec runner.

From this early experimentation we would need to add some kind of asynchronous formatter since the loading of the source maps is not instantaneous.

Would we be open to adopting the use of promises in Jasmine? This would make it a lot easier to handle these kinds of real asynchronous things. I've already made some other modifications for async style tests which I'd be happy to share.

rdy avatar Apr 06 '16 14:04 rdy

How about just implementing this for inline source maps? Surely a development setup can configure source maps to be inline and this way you don't need to make any async calls to grab the source maps.

andreisoare avatar Jun 30 '16 00:06 andreisoare

As far as I know there's no way to access the inlined source map except by doing an XHR request for the file and parsing it manually.

guncha avatar Jun 30 '16 15:06 guncha

Any update on this? It's been 6 months...

daryllabar avatar Feb 03 '17 16:02 daryllabar

This would be very beneficial.

steven-solomon avatar May 08 '17 18:05 steven-solomon

Mostly redundant with prior discussion, but since nobody's talked about this for a while:

  • If we don't want to introduce sourcemap concerns into the core codebase we can make the ExceptionFormatter injectable via Env. Extract it to a field on the options parameter, done. (Then presumably someone would write an ExceptionFormatter#stack that handles sourcemaps using one of many existing libraries.)
  • That, however, isn't that useful since any sourcemap processing you do will occur asynchronously. ExceptionFormatter#stack needs therefore to take a callback or return a promise.
  • If ExceptionFormatter#stack is asynchronous, either a whole lot of things calling it (and things that call those things) need to be asynchronous, or Spec#addExpectationResult and Suite#addExpectationResult add results to result.failedExpectations in a non-deterministic order when sourcemaps are enabled.

Any thoughts or advice, @slackersoft?

(ps. for people running into this thread: if you're using karma-jasmine with karma-webpack you should be able to get sourcemapped stacktraces out of the box. I imagine you can do the same thing with typescript as well.)

taavo avatar May 11 '17 21:05 taavo

I'd also like an update on this feature. We're wanting to switch our server-side node tests to use jasmine like our Angular apps, but since we use TypeScript server-side it makes it hard to quickly identify where in a spec file the error/assertion failure actually occurred.

johngrogg avatar Nov 21 '17 01:11 johngrogg