chore(test runner): make timeout error an Error (#29515)

This commit is contained in:
Dmitry Gozman 2024-02-15 11:38:13 -08:00 committed by GitHub
parent bd5403dcad
commit 08afb34c14
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 17 additions and 16 deletions

View File

@ -31,13 +31,14 @@ const PLAYWRIGHT_TEST_PATH = path.join(__dirname, '..');
const PLAYWRIGHT_CORE_PATH = path.dirname(require.resolve('playwright-core/package.json'));
export function filterStackTrace(e: Error): { message: string, stack: string } {
const name = e.name ? e.name + ': ' : '';
if (process.env.PWDEBUGIMPL)
return { message: e.name + ': ' + e.message, stack: e.stack || '' };
return { message: name + e.message, stack: e.stack || '' };
const stackLines = stringifyStackFrames(filteredStackTrace(e.stack?.split('\n') || []));
return {
message: e.name + ': ' + e.message,
stack: `${e.name}: ${e.message}\n${stackLines.join('\n')}`
message: name + e.message,
stack: `${name}${e.message}${stackLines.map(line => '\n' + line).join('')}`
};
}

View File

@ -226,8 +226,9 @@ export class TestInfoImpl implements TestInfo {
// consider it a timeout.
if (!this._wasInterrupted && timeoutError && !this._didTimeout) {
this._didTimeout = true;
this.errors.push(timeoutError);
this._tracing.appendForError(timeoutError);
const serialized = serializeError(timeoutError);
this.errors.push(serialized);
this._tracing.appendForError(serialized);
// Do not overwrite existing failure upon hook/teardown timeout.
if (this.status === 'passed' || this.status === 'skipped')
this.status = 'timedOut';

View File

@ -16,7 +16,6 @@
import { colors } from 'playwright-core/lib/utilsBundle';
import { TimeoutRunner, TimeoutRunnerError } from 'playwright-core/lib/utils';
import type { TestInfoError } from '../../types/test';
import type { Location } from '../../types/testReporter';
export type TimeSlot = {
@ -86,7 +85,7 @@ export class TimeoutManager {
this._timeoutRunner.updateTimeout(slot.timeout);
}
async runWithTimeout(cb: () => Promise<any>): Promise<TestInfoError | undefined> {
async runWithTimeout(cb: () => Promise<any>): Promise<Error | undefined> {
try {
await this._timeoutRunner.run(cb);
} catch (error) {
@ -127,7 +126,7 @@ export class TimeoutManager {
this._timeoutRunner.updateTimeout(slot.timeout, slot.elapsed);
}
private _createTimeoutError(): TestInfoError {
private _createTimeoutError(): Error {
let message = '';
const timeout = this._currentSlot().timeout;
switch (this._runnable.type) {
@ -174,10 +173,10 @@ export class TimeoutManager {
message = `Fixture "${fixtureWithSlot.title}" timeout of ${timeout}ms exceeded during ${fixtureWithSlot.phase}.`;
message = colors.red(message);
const location = (fixtureWithSlot || this._runnable).location;
return {
message,
const error = new Error(message);
error.name = '';
// Include location for hooks, modifiers and fixtures to distinguish between them.
stack: location ? message + `\n at ${location.file}:${location.line}:${location.column}` : undefined
};
error.stack = message + (location ? `\n at ${location.file}:${location.line}:${location.column}` : '');
return error;
}
}

View File

@ -170,7 +170,7 @@ export class WorkerMain extends ProcessRunner {
await this._fixtureRunner.teardownScope('worker', timeoutManager, e => this._fatalErrors.push(serializeError(e)));
});
if (timeoutError)
this._fatalErrors.push(timeoutError);
this._fatalErrors.push(serializeError(timeoutError));
});
}

View File

@ -354,7 +354,7 @@ test('should not report nested after hooks', async ({ runInlineTest }) => {
{
error: {
message: 'Test timeout of 2000ms exceeded.',
stack: ''
stack: 'Test timeout of 2000ms exceeded.',
},
},
]);
@ -981,7 +981,7 @@ test('should not mark page.close as failed when page.click fails', async ({ runI
{
error: {
message: 'Test timeout of 2000ms exceeded.',
stack: '',
stack: 'Test timeout of 2000ms exceeded.',
},
},
{