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 }); 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(); const testInfo = currentTestInfo();
if (!testInfo) if (!testInfo)
throw errorWithLocation(location, `test.step() can only be called from a test`); throw errorWithLocation(location, `test.step() can only be called from a test`);
@ -212,8 +212,9 @@ export class TestTypeImpl {
forceNoParent: false forceNoParent: false
}); });
try { try {
await body(); const result = await body();
step.complete({}); step.complete({});
return result;
} catch (e) { } catch (e) {
step.complete({ error: serializeError(e) }); step.complete({ error: serializeError(e) });
throw e; throw e;

View file

@ -2512,7 +2512,7 @@ export interface TestType<TestArgs extends KeyValue, WorkerArgs extends KeyValue
* @param title Step name. * @param title Step name.
* @param body Step body. * @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` function can be used to create test assertions. Read
* [expect library documentation](https://jestjs.io/docs/expect) for more details. * [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); 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; beforeAll(inner: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise<any> | any): void;
afterAll(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; 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; expect: Expect;
extend<T extends KeyValue, W extends KeyValue = {}>(fixtures: Fixtures<T, W, TestArgs, WorkerArgs>): TestType<TestArgs & T, WorkerArgs & W>; extend<T extends KeyValue, W extends KeyValue = {}>(fixtures: Fixtures<T, W, TestArgs, WorkerArgs>): TestType<TestArgs & T, WorkerArgs & W>;
info(): TestInfo; info(): TestInfo;