fix(test runner): show the location of afterAll timeout (#11007)

This commit is contained in:
Dmitry Gozman 2021-12-18 09:32:41 -08:00 committed by GitHub
parent c9ba49936f
commit 2d00836f0e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 30 additions and 8 deletions

View file

@ -173,11 +173,17 @@ export function getContainedPath(parentPath: string, subPath: string = ''): stri
export const debugTest = debug('pw:test');
export function prependToTestError(testError: TestError | undefined, message: string | undefined) {
export function prependToTestError(testError: TestError | undefined, message: string | undefined, location?: Location) {
if (!message)
return testError;
if (!testError)
return { value: message };
if (!testError) {
if (!location)
return { value: message };
let stack = ` at ${location.file}:${location.line}:${location.column}`;
if (!message.endsWith('\n'))
stack = '\n' + stack;
return { message: message, stack: message + stack };
}
if (testError.message) {
const stack = testError.stack ? message + testError.stack : testError.stack;
message = message + testError.message;

View file

@ -21,7 +21,7 @@ import * as mime from 'mime';
import util from 'util';
import colors from 'colors/safe';
import { EventEmitter } from 'events';
import { monotonicTime, serializeError, sanitizeForFilePath, getContainedPath, addSuffixToFilePath, prependToTestError, trimLongString } from './util';
import { monotonicTime, serializeError, sanitizeForFilePath, getContainedPath, addSuffixToFilePath, prependToTestError, trimLongString, formatLocation } from './util';
import { TestBeginPayload, TestEndPayload, RunPayload, TestEntry, DonePayload, WorkerInitParams, StepBeginPayload, StepEndPayload } from './ipc';
import { setCurrentTestInfo } from './globals';
import { Loader } from './loader';
@ -192,7 +192,7 @@ export class WorkerRunner extends EventEmitter {
const result = await raceAgainstDeadline(this._fixtureRunner.resolveParametersAndRunHookOrTest(beforeAllModifier.fn, this._workerInfo, undefined), this._deadline());
if (result.timedOut) {
if (!this._fatalError)
this._fatalError = serializeError(new Error(`Timeout of ${this._project.config.timeout}ms exceeded while running ${beforeAllModifier.type} modifier`));
this._fatalError = serializeError(new Error(`Timeout of ${this._project.config.timeout}ms exceeded while running ${beforeAllModifier.type} modifier\n at ${formatLocation(beforeAllModifier.location)}`));
this.stop();
}
if (!!result.result)
@ -451,7 +451,7 @@ export class WorkerRunner extends EventEmitter {
this._fatalError = testInfo.error;
// Keep any error we have, and add "timeout" message.
if (testInfo.status === 'timedOut')
this._fatalError = prependToTestError(this._fatalError, colors.red(`Timeout of ${testInfo.timeout}ms exceeded in ${test._type} hook.\n`));
this._fatalError = prependToTestError(this._fatalError, colors.red(`Timeout of ${testInfo.timeout}ms exceeded in ${test._type} hook.\n`), test.location);
}
this.stop();
} else {

View file

@ -450,7 +450,7 @@ test('beforeAll timeout should be reported', async ({ runInlineTest }) => {
expect(result.output).toContain('Timeout of 1000ms exceeded in beforeAll hook.');
});
test('afterAll timeout should be reported', async ({ runInlineTest }) => {
test('afterAll timeout should be reported', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({
'a.test.js': `
const { test } = pwt;
@ -470,6 +470,7 @@ test('afterAll timeout should be reported', async ({ runInlineTest }) => {
'%%afterAll',
]);
expect(result.output).toContain('Timeout of 1000ms exceeded in afterAll hook.');
expect(result.output).toContain(`at ${testInfo.outputPath('a.test.js')}:6:12`);
});
test('beforeAll and afterAll timeouts at the same time should be reported', async ({ runInlineTest }) => {

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
import { test, expect } from './playwright-test-fixtures';
import { test, expect, stripAscii } from './playwright-test-fixtures';
test('test modifiers should work', async ({ runInlineTest }) => {
const result = await runInlineTest({
@ -318,3 +318,18 @@ test('test.skip should not define a skipped test inside another test', async ({
expect(result.failed).toBe(1);
expect(result.output).toContain('It looks like you are calling test.skip() inside the test and pass a callback');
});
test('modifier timeout should be reported', async ({ runInlineTest }) => {
const result = await runInlineTest({
'a.test.ts': `
const { test } = pwt;
test.skip(async () => new Promise(() => {}));
test('fails', () => {
});
`,
}, { timeout: 2000 });
expect(result.exitCode).toBe(1);
expect(result.failed).toBe(1);
expect(result.output).toContain('Error: Timeout of 2000ms exceeded while running skip modifier');
expect(stripAscii(result.output)).toContain('6 | test.skip(async () => new Promise(() => {}));');
});