Karma with jsdom+custom shims/polyfills should create the right environment for the tests
- Langage dominant
- TypeScript
- Étoiles
- 27k
- Forks
- 11.8k
- Merge moyen
- 14 h 23 min
- PR mergées (30 j)
- 162
Description
# 🐞 Bug report
### Command (mark with an `x`)
- [ ] new
- [ ] build
- [ ] serve
- [X] 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:
```js
const dom = new JSDOM(`
Hello
`, {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:
```js
// 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](https://github.com/badeball/karma-jsdom-launcher/blob/3c364d8988a7a1bc8d4687ec76810cb530adfffe/index.js#L28-L40) 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
1.
```sh
$ ng new foo
$ cd foo
$ npm install karma-jsdom-launcher jsdom
```
2. Configure `angular.json` file as @badeball indicates [here ](https://github.com/badeball/karma-jsdom-launcher#i-am-using-angular-cli-and-the-test-suite-hangs-indefinitely) due to #11561 and #13580
3. Configure `karma.config.js` file as `karma-jsdom-launcher` docs indicates:
```js
// karma.config.js
...
plugins: [
....
require('karma-jsdom-launcher'),
....
],
...
browsers: ['jsdom'],
jsdomLauncher: {
jsdom: {
beforeParse(window) {
window.someCoolAPI = () => { /* ... */ };
}
}
},
...
```
4. 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
}
}
```
5.
```sh
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
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
Guide de contribution
Ouvrir le guide de contribution
Piste de recherche
Commencez par reproduire l’échec avec la configuration documentée de angular.json et karma.config.js, puis exécutez ng test en utilisant karma-jsdom-launcher et le shim beforeParse. Suivez la manière dont l’environnement jsdom atteint le contexte de test ; le travail est terminé lorsque des shims personnalisés tels que someCoolAPI ou crypto sont disponibles pendant les tests sans casser la configuration existante du launcher.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- javascript, typescript
- Domaine
- cli, testing
- Type d'issue
- Bug
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Activité
- À l'abandon
- Clarté
- Plutôt claire
- Accessibilité débutants
- 35/100