Avoid dependency common -> worker

This commit is contained in:
Yury Semikhatsky 2025-01-31 14:29:26 -08:00
parent 27586cf912
commit 822eef7d3f
2 changed files with 26 additions and 22 deletions

View file

@ -23,7 +23,6 @@ import type { Fixtures, TestType, TestDetails, TestStepInfo } from '../../types/
import type { Location } from '../../types/testReporter';
import { getPackageManagerExecCommand, monotonicTime, raceAgainstDeadline, zones } from 'playwright-core/lib/utils';
import { errors } from 'playwright-core';
import { SkipError, TestStepInfoImpl } from '../worker/testInfo';
const testTypeSymbol = Symbol('testType');
@ -263,27 +262,18 @@ export class TestTypeImpl {
const testInfo = currentTestInfo();
if (!testInfo)
throw new Error(`test.step() can only be called from a test`);
if (expectation === 'skip') {
const step = testInfo._addStep({ category: 'test.step', title, location: options.location, box: options.box });
step.annotations = [{ type: 'skip' }];
step.complete({});
return undefined as T;
}
const step = testInfo._addStep({ category: 'test.step', title, location: options.location, box: options.box });
const stepInfo = new TestStepInfoImpl(step, testInfo);
return await zones.run('stepZone', step, async () => {
try {
let result: Awaited<ReturnType<typeof raceAgainstDeadline<T>>> | undefined = undefined;
result = await raceAgainstDeadline(async () => {
try {
return await body(stepInfo);
return await step.info._runStepBody(expectation === 'skip', body);
} catch (e) {
// If the step timed out, the test fixtures will tear down, which in turn
// will abort unfinished actions in the step body. Record such errors here.
if (result?.timedOut)
testInfo._failWithError(e);
if (e instanceof SkipError)
return undefined as T;
throw e;
}
}, options.timeout ? monotonicTime() + options.timeout : 0);

View file

@ -28,11 +28,10 @@ import { debugTest, filteredStackTrace, formatLocation, getContainedPath, normal
import { TestTracing } from './testTracing';
import type { StackFrame } from '@protocol/channels';
import { testInfoError } from './util';
import { wrapFunctionWithLocation } from '../transform/transform';
export interface TestStepInternal {
complete(result: { error?: Error | unknown, suggestedRebaseline?: string }): void;
annotations?: Annotation[];
info: TestStepInfoImpl
attachmentIndices: number[];
stepId: string;
title: string;
@ -246,7 +245,7 @@ export class TestInfoImpl implements TestInfo {
?? this._findLastStageStep(this._steps); // If no parent step on stack, assume the current stage as parent.
}
_addStep(data: Omit<TestStepInternal, 'complete' | 'stepId' | 'steps' | 'attachmentIndices'>, parentStep?: TestStepInternal): TestStepInternal {
_addStep(data: Omit<TestStepInternal, 'complete' | 'stepId' | 'steps' | 'attachmentIndices' | 'info'>, parentStep?: TestStepInternal): TestStepInternal {
const stepId = `${data.category}@${++this._lastStepId}`;
if (data.isStage) {
@ -271,6 +270,7 @@ export class TestInfoImpl implements TestInfo {
...data,
steps: [],
attachmentIndices,
info: new TestStepInfoImpl(),
complete: result => {
if (step.endWallTime)
return;
@ -304,12 +304,12 @@ export class TestInfoImpl implements TestInfo {
wallTime: step.endWallTime,
error: step.error,
suggestedRebaseline: result.suggestedRebaseline,
annotations: step.annotations,
annotations: step.info.annotations,
};
this._onStepEnd(payload);
const errorForTrace = step.error ? { name: '', message: step.error.message || '', stack: step.error.stack } : undefined;
const attachments = attachmentIndices.map(i => this.attachments[i]);
this._tracing.appendAfterActionForStep(stepId, errorForTrace, attachments, step.annotations);
this._tracing.appendAfterActionForStep(stepId, errorForTrace, attachments, step.info.annotations);
}
};
const parentStepList = parentStep ? parentStep.steps : this._steps;
@ -508,20 +508,34 @@ export class TestInfoImpl implements TestInfo {
}
export class TestStepInfoImpl implements TestStepInfo {
skip;
annotations?: Annotation[];
constructor(private _step: TestStepInternal, private _testInfo: TestInfoImpl) {
this.skip = wrapFunctionWithLocation(this._skip.bind(this));
private _addAnnotation(type: string, description?: string) {
this.annotations ??= [];
this.annotations.push({ type, description });
}
private _skip(location: Location, ...args: unknown[]) {
async _runStepBody<T>(skip: boolean, body: (step: TestStepInfo) => T | Promise<T>) {
if (skip) {
this._addAnnotation('skip');
return undefined as T;
}
try {
return await body(this);
} catch (e) {
if (e instanceof SkipError)
return undefined as T;
throw e;
}
}
skip(...args: unknown[]) {
// skip();
// skip(condition: boolean, description: string);
if (args.length > 0 && !args[0])
return;
const description = args[1] as (string|undefined);
this._step.annotations ??= [];
this._step.annotations.push({ type: 'skip', description });
this._addAnnotation('skip', description);
throw new SkipError(description);
}
}