Thanks for writing ts-node for TypeScript register!
Hi, I'm writing browser mock test in jsdom.
The source code relies heavily on DOM and BOM, so I opted jsdom-global for better import behavior.
Both my source code and test code are written in TypeScript. And I use ts-node for ts extension register.
However, it seems jsdom-global breaks ts-node (or vice-versa). Something wrong with sourcemap.
Minimal setup:
npm install mocha ts-node jsdom jsdom-global
tsd install mocha node
Test code:
/// <reference path='../typings/tsd.d.ts' />
import * as assert from 'assert'
// import jsdom from 'jsdom-global'
var jsdom = require('jsdom-global')
jsdom()
describe('test sourcemap', () => {
it('should report sourcemap', () => {
assert(false)
})
})
> mocha --compilers ts:ts-node/register
/tmp/node_modules/source-map-support/source-map-support.js:407
var hasStack = (arguments[1] && arguments[1].stack);
TypeError: Invalid URL
npm ERR! Test failed. See above for more details.
And when I changed the compiler to babel (and test file extension to js). Error is reported as expected.
> mocha --compilers js:babel-register
test sourcemap
1) should report sourcemap
0 passing (46ms)
1 failing
1) test sourcemap should report sourcemap:
AssertionError: false == true
+ expected - actual
-false
+true
at Context.<anonymous> (index.js:10:3)
I think both js-dom and source-map-support, on which ts-node depends, snatched error handling to handle uncaught exception. JS-dom mocks browser environment so it naturally needs this hack. But I wonder why source-map-support requires this? And it just rudely exits the process :cold_sweat:
I'd create an issue on https://github.com/evanw/node-source-map-support and see if there's a way to resolve this.
never mind
@HerringtonDarkholme Did you manage to resolve this?
@blakeembrey I have to write up my own register script. However, it seems to work fine with mocha. ts-node still helps a lot for reference implementation. Thank ts-node!
This is closed but I was having the same issue with jsdom-global so I just wanted to add a possible solution in case anybody else comes across this, as I was bashing my head against my desk for hours before I found a solution.
I essentially could not run any mocha tests w/ ts-dom & jsdom-global (in this case I was trying to use Teaspoon, which required me to setup a window/document with jsdom). When tests would pass all would be fine, but if any test failed I would get the same error as above:
/node_modules/ts-node/node_modules/source-map-support/source-map-support.js:407
var hasStack = (arguments[1] && arguments[1].stack);
TypeError: Invalid URL
I had to scrap using jsdom-global completely, however, I was able to get away with just using jsdom, and adding the following into my own test_helper file:
import * as jsdom from 'jsdom';
const doc = jsdom.jsdom('<!doctype html><html><body></body></html>');
const win = doc.defaultView;
global['document'] = doc;
global['window'] = win;
global['navigator'] = {userAgent: 'node.js'};
global['HTMLElement'] = global['window'].HTMLElement;
Then running:
mocha --require ./src/test/helpers/test_helper.ts './src/test/**/*.ts' --compilers ts:ts-node/register
Worked as expected.
I identified the underlying issue here. When using jsdom-global with source-map-support, source-map-support believes that it is running in the browser because XMLHttpRequest exists globally.
Passing in an environment option to install() to force the "node" environment when registering with source-map-support fixes this issue.
// Install source map support and read from cache.
sourceMapSupport.install({
environment: "node",
retrieveFile (fileName) {
if (project.files[fileName]) {
return getOutput(fileName)
}
}
})
ts-node can either fix this or you can work around it by registering source-map-support yourself first and setting the right environment.
require('source-map-support').install({
environment: "node"
});
@nmalaguti Thanks for the catch, I [will] do that here.
Most helpful comment
I identified the underlying issue here. When using
jsdom-globalwithsource-map-support,source-map-supportbelieves that it is running in the browser becauseXMLHttpRequestexists globally.Passing in an environment option to
install()to force the "node" environment when registering withsource-map-supportfixes this issue.ts-nodecan either fix this or you can work around it by registeringsource-map-supportyourself first and setting the right environment.