feat: return value from step (#16060)

This commit is contained in:
Yury Semikhatsky 2022-07-29 15:16:07 -07:00 committed by GitHub
parent e830fe821d
commit 7d306bbc66
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 50 additions and 4 deletions

View file

@ -200,7 +200,7 @@ export class TestTypeImpl {
suite._use.push({ fixtures, location });
}
private async _step(location: Location, title: string, body: () => Promise<void>): Promise<void> {
private async _step<T>(location: Location, title: string, body: () => Promise<T>): Promise<T> {
const testInfo = currentTestInfo();
if (!testInfo)
throw errorWithLocation(location, `test.step() can only be called from a test`);
@ -212,8 +212,9 @@ export class TestTypeImpl {
forceNoParent: false
});
try {
await body();
const result = await body();
step.complete({});
return result;
} catch (e) {
step.complete({ error: serializeError(e) });
throw e;

View file

@ -2512,7 +2512,7 @@ export interface TestType<TestArgs extends KeyValue, WorkerArgs extends KeyValue
* @param title Step name.
* @param body Step body.
*/
step(title: string, body: () => Promise<any>): Promise<any>;
step<T>(title: string, body: () => Promise<T>): Promise<T>;
/**
* `expect` function can be used to create test assertions. Read
* [expect library documentation](https://jestjs.io/docs/expect) for more details.

View file

@ -379,3 +379,25 @@ test('should report custom expect steps', async ({ runInlineTest }) => {
},
]);
});
test('should return value from step', async ({ runInlineTest }) => {
const result = await runInlineTest({
'a.test.ts': `
const { test } = pwt;
test('steps with return values', async ({ page }) => {
const v1 = await test.step('my step', () => {
return 10;
});
console.log('v1 = ' + v1);
const v2 = await test.step('my step', async () => {
return new Promise(f => setTimeout(() => f(v1 + 10), 100));
});
console.log('v2 = ' + v2);
});
`
}, { reporter: '', workers: 1 });
expect(result.exitCode).toBe(0);
expect(result.passed).toBe(1);
expect(result.output).toContain('v1 = 10');
expect(result.output).toContain('v2 = 20');
});

View file

@ -136,3 +136,26 @@ test('test.extend options should check types', async ({ runTSC }) => {
});
expect(result.exitCode).toBe(0);
});
test('step should inherit return type from its callback ', async ({ runTSC }) => {
const result = await runTSC({
'a.spec.ts': `
const { test } = pwt;
test('my test', async ({ }) => {
// @ts-expect-error
const bad1: string = await test.step('my step', () => {
return 10;
});
// @ts-expect-error
const bad2: string = await test.step('my step', async () => {
return 10;
});
const good: string = await test.step('my step', async () => {
return 'foo';
});
await test.step('my step', async () => { });
});
`
});
expect(result.exitCode).toBe(0);
});

View file

@ -150,7 +150,7 @@ export interface TestType<TestArgs extends KeyValue, WorkerArgs extends KeyValue
beforeAll(inner: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise<any> | any): void;
afterAll(inner: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise<any> | any): void;
use(fixtures: Fixtures<{}, {}, TestArgs, WorkerArgs>): void;
step(title: string, body: () => Promise<any>): Promise<any>;
step<T>(title: string, body: () => Promise<T>): Promise<T>;
expect: Expect;
extend<T extends KeyValue, W extends KeyValue = {}>(fixtures: Fixtures<T, W, TestArgs, WorkerArgs>): TestType<TestArgs & T, WorkerArgs & W>;
info(): TestInfo;