mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
fix(test runner): do not show TimeoutError for unhandled rejection (#21971)
Unhandled error/rejection interrupts current test and produces a TimeoutError for it that should be ignored.
This commit is contained in:
parent
97d2c4a635
commit
120aaa777e
@ -53,6 +53,7 @@ export class TestInfoImpl implements TestInfo {
|
|||||||
readonly _traceEvents: trace.TraceEvent[] = [];
|
readonly _traceEvents: trace.TraceEvent[] = [];
|
||||||
readonly _onTestFailureImmediateCallbacks = new Map<() => Promise<void>, string>(); // fn -> title
|
readonly _onTestFailureImmediateCallbacks = new Map<() => Promise<void>, string>(); // fn -> title
|
||||||
_didTimeout = false;
|
_didTimeout = false;
|
||||||
|
_wasInterrupted = false;
|
||||||
_lastStepId = 0;
|
_lastStepId = 0;
|
||||||
|
|
||||||
// ------------ TestInfo fields ------------
|
// ------------ TestInfo fields ------------
|
||||||
@ -184,7 +185,7 @@ export class TestInfoImpl implements TestInfo {
|
|||||||
const timeoutError = await this._timeoutManager.runWithTimeout(cb);
|
const timeoutError = await this._timeoutManager.runWithTimeout(cb);
|
||||||
// When interrupting, we arrive here with a timeoutError, but we should not
|
// When interrupting, we arrive here with a timeoutError, but we should not
|
||||||
// consider it a timeout.
|
// consider it a timeout.
|
||||||
if (this.status !== 'interrupted' && timeoutError && !this._didTimeout) {
|
if (!this._wasInterrupted && timeoutError && !this._didTimeout) {
|
||||||
this._didTimeout = true;
|
this._didTimeout = true;
|
||||||
this.errors.push(timeoutError);
|
this.errors.push(timeoutError);
|
||||||
// Do not overwrite existing failure upon hook/teardown timeout.
|
// Do not overwrite existing failure upon hook/teardown timeout.
|
||||||
@ -254,6 +255,15 @@ export class TestInfoImpl implements TestInfo {
|
|||||||
return step;
|
return step;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_interrupt() {
|
||||||
|
// Mark as interrupted so we can ignore TimeoutError thrown by interrupt() call.
|
||||||
|
this._wasInterrupted = true;
|
||||||
|
this._timeoutManager.interrupt();
|
||||||
|
// Do not overwrite existing failure (for example, unhandled rejection) with "interrupted".
|
||||||
|
if (this.status === 'passed')
|
||||||
|
this.status = 'interrupted';
|
||||||
|
}
|
||||||
|
|
||||||
_failWithError(error: TestInfoError, isHardError: boolean) {
|
_failWithError(error: TestInfoError, isHardError: boolean) {
|
||||||
// Do not overwrite any previous hard errors.
|
// Do not overwrite any previous hard errors.
|
||||||
// Some (but not all) scenarios include:
|
// Some (but not all) scenarios include:
|
||||||
|
|||||||
@ -99,12 +99,7 @@ export class WorkerMain extends ProcessRunner {
|
|||||||
private _stop(): Promise<void> {
|
private _stop(): Promise<void> {
|
||||||
if (!this._isStopped) {
|
if (!this._isStopped) {
|
||||||
this._isStopped = true;
|
this._isStopped = true;
|
||||||
|
this._currentTest?._interrupt();
|
||||||
// Interrupt current action.
|
|
||||||
this._currentTest?._timeoutManager.interrupt();
|
|
||||||
|
|
||||||
if (this._currentTest && this._currentTest.status === 'passed')
|
|
||||||
this._currentTest.status = 'interrupted';
|
|
||||||
}
|
}
|
||||||
return this._runFinished;
|
return this._runFinished;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -394,6 +394,24 @@ test('test.{skip,fixme} should define a skipped test', async ({ runInlineTest })
|
|||||||
expect(result.output).not.toContain('%%dontseethis');
|
expect(result.output).not.toContain('%%dontseethis');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should report unhandled error during test and not report timeout', async ({ runInlineTest }) => {
|
||||||
|
const result = await runInlineTest({
|
||||||
|
'a.test.ts': `
|
||||||
|
import { test, expect } from '@playwright/test';
|
||||||
|
test('unhandled rejection', async () => {
|
||||||
|
setTimeout(() => {
|
||||||
|
throw new Error('Unhandled');
|
||||||
|
}, 0);
|
||||||
|
await new Promise(f => setTimeout(f, 100));
|
||||||
|
});
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
expect(result.exitCode).toBe(1);
|
||||||
|
expect(result.failed).toBe(1);
|
||||||
|
expect(result.output).toContain('Error: Unhandled');
|
||||||
|
expect(result.output).not.toContain('Test timeout of 30000ms exceeded');
|
||||||
|
});
|
||||||
|
|
||||||
test('should report unhandled rejection during worker shutdown', async ({ runInlineTest }) => {
|
test('should report unhandled rejection during worker shutdown', async ({ runInlineTest }) => {
|
||||||
const result = await runInlineTest({
|
const result = await runInlineTest({
|
||||||
'a.test.ts': `
|
'a.test.ts': `
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user