🐞 Bug report
Command (mark with an x)
- new
- build
- serve
- test
- e2e
- generate
- add
- update
- lint
- xi18n
- run
- config
- help
- version
- doc
Is this a regression?
No, the previous mayor version (8.x.x) the issue was present as well.
Description
We are using `jsdom` as the target browser for unit testing in our Angular library. Our library uses the `crypto` API which is not implemented in `jsdom`, so we need a shim for this API. We did it as it's indicated in its docs:
const dom = new JSDOM(`<p>Hello</p>`, {
beforeParse(window) {
window.document.childNodes.length === 0;
window.someCoolAPI = () => { /* ... */ };
}
});
Luckely the karma-json-launcher offers the posibility to configure the jsdom instance throught karma.conf.js file:
// karma.conf.js
const jsdom = require("jsdom");
module.exports = function(config) {
config.set({
browsers: ['jsdom'],
jsdomLauncher: {
jsdom: {
beforeParse(window) {
window.someCoolAPI = () => { /* ... */ };
}
}
}
});
};
The karma plugin creates the jsdom instance correctly with the passed options, and it tries to parse the url where karma is running. But unfortunalety the someCoolAPI is not present in test context inside window property and test fails with a ReferenceError: someCoolAPI is not defined
On the other hand, when you try to manually create your own jsdom instance (same way karma-json-launcher does), with someCoolAPI polyfill, and parse any html document which use that API inside it works, jsdom parses the document and the scripst are executed correctly, so that makes me think is not a jsdom or karma-jsdom-launcher problem. Can be an issue with the CLI, or Karma itself?
🔬 Minimal Reproduction
$ ng new foo
$ cd foo
$ npm install karma-jsdom-launcher jsdom
- Configure angular.json file as @badeball indicates here due to karma jsdom launcher hangs #11561 and Inability to avoid including source-map-support in Karma tests #13580
- Configure karma.config.js file as karma-jsdom-launcher docs indicates:
// karma.config.js
...
plugins: [
....
require('karma-jsdom-launcher'),
....
],
...
browsers: ['jsdom'],
jsdomLauncher: {
jsdom: {
beforeParse(window) {
window.someCoolAPI = () => { /* ... */ };
}
}
},
...
- Create app.component.ts that uses that someCoolAPI in some way.
@Component({...})
export class AppComponent {
constructor() {
window.someCoolAPI(); //the test will fail here because someCoolAPI is not defined
}
}
🔥 Exception or Error
> ng test
10% building 2/2 modules 0 active24 04 2020 23:56:59.854:WARN [karma]: No captured browser, open http://localhost:9877/
24 04 2020 23:56:59.871:INFO [karma-server]: Karma v4.4.1 server started at http://0.0.0.0:9877/
24 04 2020 23:56:59.873:INFO [launcher]: Launching browsers jsdom with concurrency unlimited
24 04 2020 23:56:59.911:INFO [launcher]: Starting browser jsdom
24 04 2020 23:57:12.239:WARN [karma]: No captured browser, open http://localhost:9877/
24 04 2020 23:57:12.552:INFO [Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/16.2.2]: Connected on socket BdQYHk1WXZIxjHKdAAAA with id 85109278
Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/16.2.2 AppComponent should create the app FAILED
ReferenceError: crypto is not defined
at
at new AppComponent (http://localhost:9877/_karma_webpack_/main.js:580:21)
at NodeInjectorFactory.AppComponent_Factory [as factory] (ng:///AppComponent/ɵfac.js:5:10)
at getNodeInjectable (http://localhost:9877/_karma_webpack_/vendor.js:41519:44)
at instantiateRootComponent (http://localhost:9877/_karma_webpack_/vendor.js:47483:23)
at createRootComponent (http://localhost:9877/_karma_webpack_/vendor.js:60827:23)
at ComponentFactory$1.create (http://localhost:9877/_karma_webpack_/vendor.js:66890:25)
at initComponent (http://localhost:9877/_karma_webpack_/vendor.js:82940:51)
at ZoneDelegate.invoke (http://localhost:9877/_karma_webpack_/polyfills.js:3836:30)
at ProxyZoneSpec.push../node_modules/zone.js/dist/zone-testing.js.ProxyZoneSpec.onInvoke (http://localhost:9877/_karma_webpack_/vendor.js:100670:43)
at ZoneDelegate.invoke (http://localhost:9877/_karma_webpack_/polyfills.js:3835:36)
Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/16.2.2: Executed 1 of 3 (1 FAILED) (0 secs / 0.294 secs)
Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/16.2.2 AppComponent should create the app FAILED
ReferenceError: crypto is not defined
at
at new AppComponent (http://localhost:9877/_karma_webpack_/main.js:580:21)
at NodeInjectorFactory.AppComponent_Factory [as factory] (ng:///AppComponent/ɵfac.js:5:10)
at getNodeInjectable (http://localhost:9877/_karma_webpack_/vendor.js:41519:44)
at instantiateRootComponent (http://localhost:9877/_karma_webpack_/vendor.js:47483:23)
at createRootComponent (http://localhost:9877/_karma_webpack_/vendor.js:60827:23)
at ComponentFactory$1.create (http://localhost:9877/_karma_webpack_/vendor.js:66890:25)
at initComponent (http://localhost:9877/_karma_webpack_/vendor.js:82940:51)
at ZoneDelegate.invoke (http://localhost:9877/_karma_webpack_/polyfills.js:3836:30)
at ProxyZoneSpec.push../node_modules/zone.js/dist/zone-testing.js.ProxyZoneSpec.onInvoke (http://localhost:9877/_karma_webpack_/vendor.js:100670:43)
🌍 Your Environment
Angular CLI: 9.1.3
Node: 12.10.0
OS: win32 x64
Angular: 9.1.3
... animations, cli, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router
Ivy Workspace: Yes
Package Version
-----------------------------------------------------------
@angular-devkit/architect 0.901.3
@angular-devkit/build-angular 0.901.3
@angular-devkit/build-optimizer 0.901.3
@angular-devkit/build-webpack 0.901.3
@angular-devkit/core 9.1.3
@angular-devkit/schematics 9.1.3
@ngtools/webpack 9.1.3
@schematics/angular 9.1.3
@schematics/update 0.901.3
rxjs 6.5.5
typescript 3.8.3
webpack 4.42.0
🐞 Bug report
Command (mark with an x)
Is this a regression?
No, the previous mayor version (8.x.x) the issue was present as well.Description
We are using `jsdom` as the target browser for unit testing in our Angular library. Our library uses the `crypto` API which is not implemented in `jsdom`, so we need a shim for this API. We did it as it's indicated in its docs:Luckely the karma-json-launcher offers the posibility to configure the jsdom instance throught karma.conf.js file:
The karma plugin creates the jsdom instance correctly with the passed options, and it tries to parse the url where karma is running. But unfortunalety the someCoolAPI is not present in test context inside window property and test fails with a ReferenceError: someCoolAPI is not defined
On the other hand, when you try to manually create your own jsdom instance (same way karma-json-launcher does), with someCoolAPI polyfill, and parse any html document which use that API inside it works, jsdom parses the document and the scripst are executed correctly, so that makes me think is not a jsdom or karma-jsdom-launcher problem. Can be an issue with the CLI, or Karma itself?
🔬 Minimal Reproduction
$ ng new foo $ cd foo $ npm install karma-jsdom-launcher jsdom@Component({...}) export class AppComponent { constructor() { window.someCoolAPI(); //the test will fail here because someCoolAPI is not defined } }ng test🔥 Exception or Error
> ng test 10% building 2/2 modules 0 active24 04 2020 23:56:59.854:WARN [karma]: No captured browser, open http://localhost:9877/ 24 04 2020 23:56:59.871:INFO [karma-server]: Karma v4.4.1 server started at http://0.0.0.0:9877/ 24 04 2020 23:56:59.873:INFO [launcher]: Launching browsers jsdom with concurrency unlimited 24 04 2020 23:56:59.911:INFO [launcher]: Starting browser jsdom 24 04 2020 23:57:12.239:WARN [karma]: No captured browser, open http://localhost:9877/ 24 04 2020 23:57:12.552:INFO [Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/16.2.2]: Connected on socket BdQYHk1WXZIxjHKdAAAA with id 85109278 Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/16.2.2 AppComponent should create the app FAILED ReferenceError: crypto is not defined at at new AppComponent (http://localhost:9877/_karma_webpack_/main.js:580:21) at NodeInjectorFactory.AppComponent_Factory [as factory] (ng:///AppComponent/ɵfac.js:5:10) at getNodeInjectable (http://localhost:9877/_karma_webpack_/vendor.js:41519:44) at instantiateRootComponent (http://localhost:9877/_karma_webpack_/vendor.js:47483:23) at createRootComponent (http://localhost:9877/_karma_webpack_/vendor.js:60827:23) at ComponentFactory$1.create (http://localhost:9877/_karma_webpack_/vendor.js:66890:25) at initComponent (http://localhost:9877/_karma_webpack_/vendor.js:82940:51) at ZoneDelegate.invoke (http://localhost:9877/_karma_webpack_/polyfills.js:3836:30) at ProxyZoneSpec.push../node_modules/zone.js/dist/zone-testing.js.ProxyZoneSpec.onInvoke (http://localhost:9877/_karma_webpack_/vendor.js:100670:43) at ZoneDelegate.invoke (http://localhost:9877/_karma_webpack_/polyfills.js:3835:36) Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/16.2.2: Executed 1 of 3 (1 FAILED) (0 secs / 0.294 secs) Mozilla/5.0 (win32) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/16.2.2 AppComponent should create the app FAILED ReferenceError: crypto is not defined at at new AppComponent (http://localhost:9877/_karma_webpack_/main.js:580:21) at NodeInjectorFactory.AppComponent_Factory [as factory] (ng:///AppComponent/ɵfac.js:5:10) at getNodeInjectable (http://localhost:9877/_karma_webpack_/vendor.js:41519:44) at instantiateRootComponent (http://localhost:9877/_karma_webpack_/vendor.js:47483:23) at createRootComponent (http://localhost:9877/_karma_webpack_/vendor.js:60827:23) at ComponentFactory$1.create (http://localhost:9877/_karma_webpack_/vendor.js:66890:25) at initComponent (http://localhost:9877/_karma_webpack_/vendor.js:82940:51) at ZoneDelegate.invoke (http://localhost:9877/_karma_webpack_/polyfills.js:3836:30) at ProxyZoneSpec.push../node_modules/zone.js/dist/zone-testing.js.ProxyZoneSpec.onInvoke (http://localhost:9877/_karma_webpack_/vendor.js:100670:43)🌍 Your Environment