angular / angular/angular-cli

Karma with jsdom+custom shims/polyfills should create the right environment for the tests

未關閉
#17,547 0 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視
area: @angular-devkit/build-angular devkit/build-angular:karma help wanted
主要語言
TypeScript
星號
27k
分支
11.8k
平均合併
14 小時 23 分鐘
30 天內合併 PR
162

描述

# 🐞 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

貢獻指南

開啟貢獻指南

研究方向

先使用文件所述的 angular.json 和 karma.config.js 設定重現此故障,然後使用 karma-jsdom-launcher 和 beforeParse shim 執行 ng test。追蹤 jsdom 環境如何到達測試內容;完成的標準是,自訂 shim(例如 someCoolAPI 或 crypto)能在測試期間使用,同時不會破壞現有的 launcher 設定。

由索引模型根據 Issue 內容生成。

評估

技術堆疊
javascript, typescript
領域
cli, testing
Issue 類型
缺陷
難度
4/5
預估耗時
3-5 天
活躍度
停滯
描述清晰度
基本清楚
新手友好度
35/100

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。