chore(test runner): do not rely on zones for fixture steps (#29519)
This commit is contained in:
parent
05e6b5b5c7
commit
dbf0b25146
|
|
@ -15,7 +15,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { formatLocation, debugTest, filterStackFile } from '../util';
|
import { formatLocation, debugTest, filterStackFile } from '../util';
|
||||||
import { ManualPromise, zones } from 'playwright-core/lib/utils';
|
import { ManualPromise } from 'playwright-core/lib/utils';
|
||||||
import type { TestInfoImpl, TestStepInternal } from './testInfo';
|
import type { TestInfoImpl, TestStepInternal } from './testInfo';
|
||||||
import type { FixtureDescription, TimeoutManager } from './timeoutManager';
|
import type { FixtureDescription, TimeoutManager } from './timeoutManager';
|
||||||
import { fixtureParameterNames, type FixturePool, type FixtureRegistration, type FixtureScope } from '../common/fixtures';
|
import { fixtureParameterNames, type FixturePool, type FixtureRegistration, type FixtureScope } from '../common/fixtures';
|
||||||
|
|
@ -78,7 +78,7 @@ class Fixture {
|
||||||
// w/o scopes, and create single mutable step that will be converted into the after step.
|
// w/o scopes, and create single mutable step that will be converted into the after step.
|
||||||
const shouldGenerateStep = !this.registration.hideStep && !this.registration.name.startsWith('_') && !this.registration.option;
|
const shouldGenerateStep = !this.registration.hideStep && !this.registration.name.startsWith('_') && !this.registration.option;
|
||||||
const isInternalFixture = this.registration.location && filterStackFile(this.registration.location.file);
|
const isInternalFixture = this.registration.location && filterStackFile(this.registration.location.file);
|
||||||
let mutableStepOnStack: TestStepInternal | undefined;
|
let beforeStep: TestStepInternal | undefined;
|
||||||
let afterStep: TestStepInternal | undefined;
|
let afterStep: TestStepInternal | undefined;
|
||||||
|
|
||||||
let called = false;
|
let called = false;
|
||||||
|
|
@ -89,6 +89,7 @@ class Fixture {
|
||||||
throw new Error(`Cannot provide fixture value for the second time`);
|
throw new Error(`Cannot provide fixture value for the second time`);
|
||||||
called = true;
|
called = true;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
|
beforeStep?.complete({});
|
||||||
this._useFuncFinished = new ManualPromise<void>();
|
this._useFuncFinished = new ManualPromise<void>();
|
||||||
useFuncStarted.resolve();
|
useFuncStarted.resolve();
|
||||||
await this._useFuncFinished;
|
await this._useFuncFinished;
|
||||||
|
|
@ -100,7 +101,6 @@ class Fixture {
|
||||||
category: 'fixture',
|
category: 'fixture',
|
||||||
location: isInternalFixture ? this.registration.location : undefined,
|
location: isInternalFixture ? this.registration.location : undefined,
|
||||||
});
|
});
|
||||||
mutableStepOnStack!.stepId = afterStep.stepId;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -108,44 +108,31 @@ class Fixture {
|
||||||
const info = this.registration.scope === 'worker' ? workerInfo : testInfo;
|
const info = this.registration.scope === 'worker' ? workerInfo : testInfo;
|
||||||
testInfo._timeoutManager.setCurrentFixture(this._runnableDescription);
|
testInfo._timeoutManager.setCurrentFixture(this._runnableDescription);
|
||||||
|
|
||||||
const handleError = (e: any) => {
|
|
||||||
this.failed = true;
|
|
||||||
if (!useFuncStarted.isDone())
|
|
||||||
useFuncStarted.reject(e);
|
|
||||||
else
|
|
||||||
throw e;
|
|
||||||
};
|
|
||||||
try {
|
|
||||||
const result = zones.preserve(async () => {
|
|
||||||
if (!shouldGenerateStep)
|
|
||||||
return await this.registration.fn(params, useFunc, info);
|
|
||||||
|
|
||||||
await testInfo._runAsStep({
|
|
||||||
title: `fixture: ${this.registration.name}`,
|
|
||||||
category: 'fixture',
|
|
||||||
location: isInternalFixture ? this.registration.location : undefined,
|
|
||||||
}, async step => {
|
|
||||||
mutableStepOnStack = step;
|
|
||||||
return await this.registration.fn(params, useFunc, info);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
if (result instanceof Promise)
|
|
||||||
this._selfTeardownComplete = result.catch(handleError);
|
|
||||||
else
|
|
||||||
this._selfTeardownComplete = Promise.resolve();
|
|
||||||
} catch (e) {
|
|
||||||
handleError(e);
|
|
||||||
}
|
|
||||||
await useFuncStarted;
|
|
||||||
if (shouldGenerateStep) {
|
if (shouldGenerateStep) {
|
||||||
mutableStepOnStack?.complete({});
|
beforeStep = testInfo._addStep({
|
||||||
this._selfTeardownComplete?.then(() => {
|
title: `fixture: ${this.registration.name}`,
|
||||||
afterStep?.complete({});
|
category: 'fixture',
|
||||||
}).catch(e => {
|
location: isInternalFixture ? this.registration.location : undefined,
|
||||||
afterStep?.complete({ error: e });
|
wallTime: Date.now(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._selfTeardownComplete = (async () => {
|
||||||
|
try {
|
||||||
|
await this.registration.fn(params, useFunc, info);
|
||||||
|
afterStep?.complete({});
|
||||||
|
} catch (error) {
|
||||||
|
beforeStep?.complete({ error });
|
||||||
|
afterStep?.complete({ error });
|
||||||
|
this.failed = true;
|
||||||
|
if (!useFuncStarted.isDone())
|
||||||
|
useFuncStarted.reject(error);
|
||||||
|
else
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
await useFuncStarted;
|
||||||
testInfo._timeoutManager.setCurrentFixture(undefined);
|
testInfo._timeoutManager.setCurrentFixture(undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -269,7 +269,11 @@ export class TestInfoImpl implements TestInfo {
|
||||||
parentStep = this._findLastNonFinishedStep(step => step.category === 'fixture' || step.category === 'hook');
|
parentStep = this._findLastNonFinishedStep(step => step.category === 'fixture' || step.category === 'hook');
|
||||||
} else {
|
} else {
|
||||||
parentStep = zones.zoneData<TestStepInternal>('stepZone', rawStack!) || undefined;
|
parentStep = zones.zoneData<TestStepInternal>('stepZone', rawStack!) || undefined;
|
||||||
if (!parentStep) {
|
if (parentStep?.category === 'hook' || parentStep?.category === 'fixture') {
|
||||||
|
// Prefer last non-finished predefined step over the on-stack one, because
|
||||||
|
// some predefined steps may be missing on the stack.
|
||||||
|
parentStep = this._findLastNonFinishedStep(step => step.category === 'fixture' || step.category === 'hook');
|
||||||
|
} else if (!parentStep) {
|
||||||
if (data.category === 'test.step') {
|
if (data.category === 'test.step') {
|
||||||
// Nest test.step without a good stack in the last non-finished predefined step like a hook.
|
// Nest test.step without a good stack in the last non-finished predefined step like a hook.
|
||||||
parentStep = this._findLastNonFinishedStep(step => step.category === 'fixture' || step.category === 'hook');
|
parentStep = this._findLastNonFinishedStep(step => step.category === 'fixture' || step.category === 'hook');
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue