From c47af2d4f3750ecf40f26d1513fc1ae1b8fbe6d4 Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Fri, 28 Aug 2020 18:25:09 -0700 Subject: [PATCH] fix(testrunner): report unhandled rejection ones, allow retry (#3686) --- test-runner/src/testRunner.ts | 8 ++++++- .../test/assets/unhandled-rejection.js | 23 +++++++++++++++++++ test-runner/test/exit-code.spec.ts | 9 ++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 test-runner/test/assets/unhandled-rejection.js diff --git a/test-runner/src/testRunner.ts b/test-runner/src/testRunner.ts index 8dedb4821f..61ab2034da 100644 --- a/test-runner/src/testRunner.ts +++ b/test-runner/src/testRunner.ts @@ -78,11 +78,14 @@ export class TestRunner extends EventEmitter { unhandledError(error: Error | any) { if (this._testResult) { + this._testResult.status = 'failed'; this._testResult.error = serializeError(error); + this._failedTestId = this._testId; this.emit('testEnd', { id: this._testId, result: this._testResult }); + this._testResult = null; } else if (!this._loaded) { // No current test - fatal error. this._fatalError = serializeError(error); @@ -197,7 +200,10 @@ export class TestRunner extends EventEmitter { result.error = serializeError(error); } result.duration = Date.now() - startTime; - this.emit('testEnd', { id, result }); + if (this._testResult) { + // We could have reported end due to an unhandled exception. + this.emit('testEnd', { id, result }); + } if (result.status !== 'passed') this._failedTestId = this._testId; this._testResult = null; diff --git a/test-runner/test/assets/unhandled-rejection.js b/test-runner/test/assets/unhandled-rejection.js new file mode 100644 index 0000000000..8bf0d72941 --- /dev/null +++ b/test-runner/test/assets/unhandled-rejection.js @@ -0,0 +1,23 @@ +/** + * Copyright (c) Microsoft Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +require('../../'); + +it('unhandled rejection', async () => { + setTimeout(() => { + throw new Error('Unhandled rejection in the test'); + }); + await new Promise(f => setTimeout(f, 20)); +}); diff --git a/test-runner/test/exit-code.spec.ts b/test-runner/test/exit-code.spec.ts index c9f557b544..b6567a28e3 100644 --- a/test-runner/test/exit-code.spec.ts +++ b/test-runner/test/exit-code.spec.ts @@ -162,6 +162,15 @@ it('should respect nested skip', async () => { expect(skipped).toBe(1); }); +it('should retry unhandled rejection', async () => { + const result = await runTest('unhandled-rejection.js', { retries: 2 }); + expect(result.exitCode).toBe(1); + expect(result.passed).toBe(0); + expect(result.failed).toBe(1); + expect(result.output.split('\n')[0]).toBe(colors.red('F').repeat(3)); + expect(result.output).toContain('Unhandled rejection'); +}); + async function runTest(filePath: string, params: any = {}) { const outputDir = path.join(__dirname, 'test-results'); const reportFile = path.join(outputDir, 'results.json');