badeball / karma-jsdom-launcher

A Karma plugin. Launcher for jsdom.
MIT License
37 stars 16 forks source link

angular 8 and problems with zone-aware promise #29

Closed marcorinck closed 5 years ago

marcorinck commented 5 years ago

I'm having a problem running my unit tests in my angular 8 cli projects and jsdom. They were working without any problems with angular 7 and jsdom.

After updating to angular 8 I get this error message for every unit test:

 Error: Zone.js has detected that ZoneAwarePromise `(window|global).Promise` has been overwritten.
        Most likely cause is that a Promise polyfill has been loaded after Zone.js (Polyfilling Promise api is not necessary when zone.js is loaded. If you must load one, do so before loading zone.js.)
        error properties: Object({ originalStack: 'Error: Zone.js has detected that ZoneAwarePromise `(window|global).Promise` has been overwritten.
            at new ZoneAwareError (http://localhost:9876/_karma_webpack_/vendor.js:154582:33)
            at Function.assertZonePatched (http://localhost:9876/_karma_webpack_/polyfills.js:3018:23)
            at new NgZone (http://localhost:9876/_karma_webpack_/vendor.js:91257:14)
            at TestBedViewEngine._initIfNeeded (http://localhost:9876/_karma_webpack_/vendor.js:100586:24)
            at TestBedViewEngine.createComponent (http://localhost:9876/_karma_webpack_/vendor.js:100842:14)
            at Function.createComponent (http://localhost:9876/_karma_webpack_/vendor.js:100426:40)
            at UserContext.beforeEach (http://localhost:9876/_karma_webpack_/main.js:1598:81)
            at ZoneDelegate.invoke (http://localhos ...
            at <Jasmine>
        Error: Expected undefined to be truthy.
        error properties: Object({ originalStack: '
            at new ZoneAwareError (http://localhost:9876/_karma_webpack_/vendor.js:154582:33)
            at Expector.addExpectationResult (/ ...
        Error: Expected undefined to be truthy.

I'm not really sure what is causing this problem. I'm only importing zone once in polyfills.ts of course and have updated all dependencies to the current version:

Unit tests are still running fine in Chrome.

badeball commented 5 years ago

Hi, @marcorinck

I've created a fresh Angular CLI project and managed to reproduce the issue. It turns out that Angular will include two polyfills - your own (containing zone.js) and then core-js (see ./node_modules/@angular-devkit/build-angular/src/angular-cli-files/models/es5-polyfills.js).

core-js will overwrite zone.js' Promise implementation with their own and that's where the error comes from. You can for instance wipe the content of ./browserlist and see that the tests suddenly pass.

My guess is that this will also affect real browsers that exhibit similar properties as jsdom. The same error can be seen in EG. Edge 15.

I'm sorry to say that I don't believe this is a problem with karma-jsdom-launcher (nor do I believe it's jdom's issue). I tried to get some insight into what Angular is doing nowdays, but that seems like mission impossible.

... fast forward a bit ...

As I was writing this post, I ventured into the source of angular-cli [1] and discovered that this has in fact been reported [2] and fixed [3]. You can probably expect a release in near future containing it.

[1] https://github.com/angular/angular-cli/blob/v8.0.2/packages/angular_devkit/build_angular/src/angular-cli-files/plugins/karma-context.html [2] https://github.com/angular/angular-cli/issues/14618 [3] https://github.com/angular/angular-cli/pull/14693