I have an angular 7 application which runs its e2e tests during a CI pipeline on a server. My server's package manager updated the node.js version from 10.14 to 10.14.2 (Both LTS versions) This causes ng e2e to throw the following error:
i 「wdm」: Compiled successfully.
[13:38:47] I/update - chromedriver: file exists node_modules\webdriver-manager\selenium\chromedriver_2.45.zip
[13:38:47] I/update - chromedriver: unzipping chromedriver_2.45.zip
[13:38:48] I/update - chromedriver: chromedriver_2.45.exe up to date
events.js:167
throw er; // Unhandled 'error' event
^
Error: write EPIPE
at ChildProcess.target._send (internal/child_process.js:742:20)
at ChildProcess.target.send (internal/child_process.js:626:19)
at Observable.rxjs_1.Observable.obs [as _subscribe] (node_modules\@angular-devkit\build-angular\src\utils\run-module-as-observable-fork.js:57:23)
at Observable._trySubscribe (node_modules\rxjs\internal\Observable.js:44:25)
at Observable.subscribe (node_modules\rxjs\internal\Observable.js:30:22)
at node_modules\rxjs\internal\util\subscribeTo.js:22:31
at Object.subscribeToResult (node_modules\rxjs\internal\util\subscribeToResult.js:10:45)
at MergeMapSubscriber._innerSub (node_modules\rxjs\internal\operators\mergeMap.js:82:29)
at MergeMapSubscriber._tryNext (node_modules\rxjs\internal\operators\mergeMap.js:76:14)
at MergeMapSubscriber._next (node_modules\rxjs\internal\operators\mergeMap.js:59:18)
at MergeMapSubscriber.Subscriber.next (node_modules\rxjs\internal\Subscriber.js:67:18)
at MergeMapSubscriber.notifyNext (node_modules\rxjs\internal\operators\mergeMap.js:92:26)
at InnerSubscriber._next (node_modules\rxjs\internal\InnerSubscriber.js:28:21)
at InnerSubscriber.Subscriber.next (node_modules\rxjs\internal\Subscriber.js:67:18)
at node_modules\rxjs\internal\util\subscribeToPromise.js:7:24
at process._tickCallback (internal/process/next_tick.js:68:7)
Emitted 'error' event at:
at process.nextTick (internal/child_process.js:746:39)
at process._tickCallback (internal/process/next_tick.js:61:11)
I was able to reproduce this locally, when i rollback to 10.14 ng e2e works again.
package.json:
"dependencies": {
"@angular-devkit/build-angular": "~0.10.0",
"@angular/animations": "^7.0.1",
"@angular/cdk": "^7.0.2",
"@angular/common": "^7.0.1",
"@angular/compiler": "^7.0.1",
"@angular/core": "^7.0.1",
"@angular/forms": "^7.0.1",
"@angular/http": "^7.0.1",
"@angular/material": "^7.0.2",
"@angular/platform-browser": "^7.0.1",
"@angular/platform-browser-dynamic": "^7.0.1",
"@angular/platform-server": "^7.0.1",
"@angular/router": "^7.0.1",
"@ng-bootstrap/ng-bootstrap": "^4.0.0",
"@ngx-translate/core": "^11.0.0",
"@ngx-translate/http-loader": "^4.0.0",
"aspnet-prerendering": "^3.0.1",
"bootstrap": "^4.1.3",
"classlist.js": "^1.1.20150312",
"core-js": "^2.5.7",
"devextreme": "18.1.4",
"devextreme-angular": "18.1.4",
"devextreme-aspnet-data": "1.4.5",
"lodash": "^4.17.11",
"node-sass": "^4.10.0",
"rxjs": "^6.3.3",
"toastr": "^2.1.4",
"webpack": "^4.19.1",
"zone.js": "^0.8.26"
},
"devDependencies": {
"@angular-devkit/core": "0.8.3",
"@angular/cli": "^7.0.3",
"@angular/compiler-cli": "^7.0.1",
"@angular/language-service": "^7.0.1",
"@babel/core": "^7.1.2",
"@compodoc/compodoc": "^1.1.5",
"@storybook/addon-actions": "^4.0.0",
"@storybook/addon-knobs": "^4.0.0",
"@storybook/addon-links": "^4.0.0",
"@storybook/addon-notes": "^4.0.0",
"@storybook/addons": "^4.0.0",
"@storybook/angular": "^4.0.0",
"@types/jasmine": "~2.8.8",
"@types/jasminewd2": "~2.0.3",
"@types/jquery": "^3.3.9",
"@types/node": "^10.12.1",
"@types/react": "^16.4.14",
"@types/toastr": "^2.1.35",
"babel-loader": "^8.0.4",
"codelyzer": "^4.5.0",
"jasmine": "3.2.0",
"jasmine-core": "3.2.0",
"jasmine-reporters": "^2.3.2",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~2.0.4",
"karma-chrome-launcher": "~2.2.0",
"karma-cli": "~1.0.1",
"karma-coverage-istanbul-reporter": "^2.0.1",
"karma-jasmine": "^1.1.2",
"karma-jasmine-html-reporter": "1.3.1",
"karma-junit-reporter": "^1.2.0",
"ngx-perfect-scrollbar": "^7.0.0",
"prettier": "^1.14.3",
"protractor": "^5.4.1",
"react": "^16.5.2",
"react-dom": "^16.5.2",
"ts-node": "~7.0.1",
"tslint": "~5.11.0",
"tslint-config-prettier": "^1.15.0",
"tslint-plugin-prettier": "^2.0.0",
"typescript": "^3.1.3",
"webdriver-manager": "^12.1.0",
"webpack-bundle-analyzer": "^3.0.3"
}
Any idea what exactly causes this and how it can be fixed?
In fact, as mentioned in one of the comments, updating to the newest Angular CLI
version did the job. Patch was released, so there is no necessity to downgrade the nodejs
as suggested in the link above.
EPIPE errors were appearing, because tests (in TypeScript) were incorrectly using awaits. And therefore unhandled Promise rejections were happening randomly and leading to these errors. Once I've fixed incorrect usages we don't have these errors anymore on Node 10.
Try to check your tests carefully for incorrect usages of await (either missing or redundant) or just incorrect Promise chaining (for example when you forgot to return Promise from helper methods). In our case typical error was using:
browser.wait(await EC.invisibilityOf(fade)); // incorrect
instead of:
await browser.wait(EC.invisibilityOf(fade)); // correct
Update my answer the alternative solution
The following code can be called in Protractor's onPrepare()
hook, for example
let currentCommand = Promise.resolve();
// Serialise all webdriver commands to prevent EPIPE errors
const webdriverSchedule = browser.driver.schedule;
browser.driver.schedule = (command: Command, description: string) => {
currentCommand = currentCommand.then(() =>
webdriverSchedule.call(browser.driver, command, description)
);
return currentCommand as any;
}
or with some additional logging:
let currentCommand = Promise.resolve();
let concurrencyCounter = 0;
// Serialise all webdriver commands to prevent EPIPE errors
const webdriverSchedule = browser.driver.schedule;
browser.driver.schedule = (command: Command, description: string) => {
console.log(`${++concurrencyCounter} concurrent webdriver command(s). Latest command: ${description}`);
currentCommand = currentCommand.then(() =>
webdriverSchedule.call(browser.driver, command, description)
.then(result => {
concurrencyCounter--;
return result;
})
.catch(error => {
concurrencyCounter--;
//console.lgErrLabel('Webdriver error')(command, description, error);
console.error('Webdriver error:', command, description, error);
throw error;
})
);
return currentCommand as any;
}
Maybe it will help somebody, who also has this issue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With