From 95ab5f3e0f4762c7113494aa5dd50ba48b884f60 Mon Sep 17 00:00:00 2001 From: osohyun0224 <53892427+osohyun0224@users.noreply.github.com> Date: Sun, 8 Sep 2024 15:54:38 +0900 Subject: [PATCH] feat :: allow to pass arbitrary location to test.step --- examples/todomvc/tests/integration.spec.ts | 5 ++-- packages/playwright/src/common/fixtures.ts | 2 +- packages/playwright/src/common/testType.ts | 4 ++-- packages/playwright/types/test.d.ts | 10 ++++---- tests/playwright-test/buttonClick.spec.ts | 24 +++++++++++++++++++ tests/playwright-test/helpers.ts | 27 ++++++++++++++++++++++ utils/generate_types/overrides-test.d.ts | 10 ++++---- 7 files changed, 67 insertions(+), 15 deletions(-) create mode 100644 tests/playwright-test/buttonClick.spec.ts create mode 100644 tests/playwright-test/helpers.ts diff --git a/examples/todomvc/tests/integration.spec.ts b/examples/todomvc/tests/integration.spec.ts index 007896bb2c..4e895063bf 100644 --- a/examples/todomvc/tests/integration.spec.ts +++ b/examples/todomvc/tests/integration.spec.ts @@ -2,7 +2,8 @@ import { test, expect } from '@playwright/test'; import type { Page } from '@playwright/test'; - +import { hostname } from "os"; +import type { Location } from '../../../packages/playwright/types/testReporter' test.describe.configure({ mode: 'parallel' }); test.beforeEach(async ({ page }) => { @@ -362,7 +363,7 @@ test.describe('Routing', () => { await test.step('Showing active items', async () => { await page.getByRole('link', { name: 'Active' }).click(); - }); + }, {location}); await test.step('Showing completed items', async () => { await page.getByRole('link', { name: 'Completed' }).click(); diff --git a/packages/playwright/src/common/fixtures.ts b/packages/playwright/src/common/fixtures.ts index 6b50947ab5..156009ef4c 100644 --- a/packages/playwright/src/common/fixtures.ts +++ b/packages/playwright/src/common/fixtures.ts @@ -23,7 +23,7 @@ import type { FixturesWithLocation } from './config'; export type FixtureScope = 'test' | 'worker'; type FixtureAuto = boolean | 'all-hooks-included'; const kScopeOrder: FixtureScope[] = ['test', 'worker']; -type FixtureOptions = { auto?: FixtureAuto, scope?: FixtureScope, option?: boolean, timeout?: number | undefined, title?: string, box?: boolean }; +type FixtureOptions = { auto?: FixtureAuto, scope?: FixtureScope, option?: boolean, timeout?: number | undefined, title?: string, box?: boolean, location?: Location }; type FixtureTuple = [ value: any, options: FixtureOptions ]; export type FixtureRegistration = { // Fixture registration location. diff --git a/packages/playwright/src/common/testType.ts b/packages/playwright/src/common/testType.ts index 5c7850a3df..f0882735dc 100644 --- a/packages/playwright/src/common/testType.ts +++ b/packages/playwright/src/common/testType.ts @@ -259,11 +259,11 @@ export class TestTypeImpl { suite._use.push({ fixtures, location }); } - async _step(title: string, body: () => Promise, options: { box?: boolean } = {}): Promise { + async _step(title: string, body: () => Promise, options: {box?: boolean, location?: Location } = {}): Promise { const testInfo = currentTestInfo(); if (!testInfo) throw new Error(`test.step() can only be called from a test`); - const step = testInfo._addStep({ category: 'test.step', title, box: options.box }); + const step = testInfo._addStep({ category: 'test.step', title, location: options.location, box: options.box }); return await zones.run('stepZone', step, async () => { try { const result = await body(); diff --git a/packages/playwright/types/test.d.ts b/packages/playwright/types/test.d.ts index 09b5c7efdb..537237f99f 100644 --- a/packages/playwright/types/test.d.ts +++ b/packages/playwright/types/test.d.ts @@ -4703,7 +4703,7 @@ export interface TestType(title: string, body: () => T | Promise, options?: { box?: boolean }): Promise; + step(title: string, body: () => T | Promise, options?: { box?: boolean, location?: Location }): Promise; /** * `expect` function can be used to create test assertions. Read more about [test assertions](https://playwright.dev/docs/test-assertions). * @@ -4811,13 +4811,13 @@ export type WorkerFixture = (args: Args, use: (r: R) = type TestFixtureValue = Exclude | TestFixture; type WorkerFixtureValue = Exclude | WorkerFixture; export type Fixtures = { - [K in keyof PW]?: WorkerFixtureValue | [WorkerFixtureValue, { scope: 'worker', timeout?: number | undefined, title?: string, box?: boolean }]; + [K in keyof PW]?: WorkerFixtureValue | [WorkerFixtureValue, { scope: 'worker', timeout?: number | undefined, title?: string, box?: boolean, location? : Location}]; } & { - [K in keyof PT]?: TestFixtureValue | [TestFixtureValue, { scope: 'test', timeout?: number | undefined, title?: string, box?: boolean }]; + [K in keyof PT]?: TestFixtureValue | [TestFixtureValue, { scope: 'test', timeout?: number | undefined, title?: string, box?: boolean, location? : Location}]; } & { - [K in keyof W]?: [WorkerFixtureValue, { scope: 'worker', auto?: boolean, option?: boolean, timeout?: number | undefined, title?: string, box?: boolean }]; + [K in keyof W]?: [WorkerFixtureValue, { scope: 'worker', auto?: boolean, option?: boolean, timeout?: number | undefined, title?: string, box?: boolean, location? : Location}]; } & { - [K in keyof T]?: TestFixtureValue | [TestFixtureValue, { scope?: 'test', auto?: boolean, option?: boolean, timeout?: number | undefined, title?: string, box?: boolean }]; + [K in keyof T]?: TestFixtureValue | [TestFixtureValue, { scope?: 'test', auto?: boolean, option?: boolean, timeout?: number | undefined, title?: string, box?: boolean, location?: Location }]; }; type BrowserName = 'chromium' | 'firefox' | 'webkit'; diff --git a/tests/playwright-test/buttonClick.spec.ts b/tests/playwright-test/buttonClick.spec.ts new file mode 100644 index 0000000000..cd87b155af --- /dev/null +++ b/tests/playwright-test/buttonClick.spec.ts @@ -0,0 +1,24 @@ +/** + * Copyright (c) Microsoft Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { test, expect } from './playwright-test-fixtures'; +import { clickButton } from './helpers'; + +test('should click the button successfully', async ({ page }) => { + await page.goto('https://example.com'); + await clickButton(page, '#submit-button'); + expect(await page.isVisible('#confirmation')).toBeTruthy(); +}); \ No newline at end of file diff --git a/tests/playwright-test/helpers.ts b/tests/playwright-test/helpers.ts new file mode 100644 index 0000000000..de9540151b --- /dev/null +++ b/tests/playwright-test/helpers.ts @@ -0,0 +1,27 @@ +/** + * Copyright (c) Microsoft Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { test } from './stable-test-runner'; + +export async function clickButton(page, selector: string) { + return test.step(`Click on button with selector ${selector}`, async () => { + await page.click(selector); + }); +} + +export async function clickButton2(text: string) { + return test.step('dummy step', () => clickButton('helpers', text)); +} \ No newline at end of file diff --git a/utils/generate_types/overrides-test.d.ts b/utils/generate_types/overrides-test.d.ts index 90ef7fa75a..77c2a391a4 100644 --- a/utils/generate_types/overrides-test.d.ts +++ b/utils/generate_types/overrides-test.d.ts @@ -128,7 +128,7 @@ export interface TestType Promise | any): void; afterAll(title: string, inner: (args: TestArgs & WorkerArgs, testInfo: TestInfo) => Promise | any): void; use(fixtures: Fixtures<{}, {}, TestArgs, WorkerArgs>): void; - step(title: string, body: () => T | Promise, options?: { box?: boolean }): Promise; + step(title: string, body: () => T | Promise, options?: { box?: boolean, location?: Location }): Promise; expect: Expect<{}>; extend(fixtures: Fixtures): TestType; info(): TestInfo; @@ -140,13 +140,13 @@ export type WorkerFixture = (args: Args, use: (r: R) = type TestFixtureValue = Exclude | TestFixture; type WorkerFixtureValue = Exclude | WorkerFixture; export type Fixtures = { - [K in keyof PW]?: WorkerFixtureValue | [WorkerFixtureValue, { scope: 'worker', timeout?: number | undefined, title?: string, box?: boolean }]; + [K in keyof PW]?: WorkerFixtureValue | [WorkerFixtureValue, { scope: 'worker', timeout?: number | undefined, title?: string, box?: boolean, location?: Location }]; } & { - [K in keyof PT]?: TestFixtureValue | [TestFixtureValue, { scope: 'test', timeout?: number | undefined, title?: string, box?: boolean }]; + [K in keyof PT]?: TestFixtureValue | [TestFixtureValue, { scope: 'test', timeout?: number | undefined, title?: string, box?: boolean, location?: Location}]; } & { - [K in keyof W]?: [WorkerFixtureValue, { scope: 'worker', auto?: boolean, option?: boolean, timeout?: number | undefined, title?: string, box?: boolean }]; + [K in keyof W]?: [WorkerFixtureValue, { scope: 'worker', auto?: boolean, option?: boolean, timeout?: number | undefined, title?: string, box?: boolean, location?: Location }]; } & { - [K in keyof T]?: TestFixtureValue | [TestFixtureValue, { scope?: 'test', auto?: boolean, option?: boolean, timeout?: number | undefined, title?: string, box?: boolean }]; + [K in keyof T]?: TestFixtureValue | [TestFixtureValue, { scope?: 'test', auto?: boolean, option?: boolean, timeout?: number | undefined, title?: string, box?: boolean, location?: Location }]; }; type BrowserName = 'chromium' | 'firefox' | 'webkit';