jasmine
jasmine copied to clipboard
Feature Request: Sourcemap support
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
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?
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.
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 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
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 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, 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.
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...
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.
+1 this would be useful for running unit tests written in Typescript
:+1: I compile all my tests beforehand using typescript. Source map support would be really nice. I hate digging through the generated file.
+1 as someone using webpack, I have no idea where the actual errors are without source map support.
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.
+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?
sorry, you definitely have to patch Jasmine..
@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
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
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.
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 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.
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.
Is there a different JavaScript test runner that handles sourcemaps??
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.
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.
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.
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.
Any update on this? It's been 6 months...
This would be very beneficial.
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 viaEnv
. Extract it to a field on theoptions
parameter, done. (Then presumably someone would write anExceptionFormatter#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, orSpec#addExpectationResult
andSuite#addExpectationResult
add results toresult.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.)
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.