playwright icon indicating copy to clipboard operation
playwright copied to clipboard

[Feature]: Ability to access custom TestDetails through TestInfo directly inside TestHook!

Open MrVerifit opened this issue 1 year ago • 5 comments

🚀 Feature Request

I would like to request a way to access custom TestDetails inside testHook

Example

Accessing CustomTestDetails through TestInfo

import {
  TestType,
  TestInfo,
  PlaywrightTestArgs,
  PlaywrightTestOptions,
  PlaywrightWorkerArgs,
  PlaywrightWorkerOptions,
  TestDetails
} from "@playwright/test";

interface EnvItem {
    plugin?: string;
    site?: string;
}

export interface CustomTestDetails extends TestDetails {
  envs?: EnvItem[];
  resetDatabase?: boolean;
}

export type CustomTestArgs = PlaywrightTestArgs & PlaywrightTestOptions;
export type CustomWorkerArgs = PlaywrightWorkerArgs & PlaywrightWorkerOptions;

export interface CustomTestType<T, W> extends TestType<T, W> {
  (title: string, detail: CustomTestDetails, testBody: (args: T, testInfo: TestInfo) => Promise<void> | void): void;
}

interface WPTestArgs {
    testHook: void,
    wpdb: Wpdb
}

export const test = base.extend<WPTestArgs>({
    wpdb: async ({}, use) => {
        const wpdb = Wpdb.getInstance();
        await use(wpdb);
    },
    testHook: [
        async ({}, use, testInfo: TestInfo) => {
            const details = testInfo.details(); // This is what I would like to have to access custom TestDetails
            await beforeHook(testInfo);
            await use();
            await afterHook(testInfo);
        },
        { auto: true },
    ],
}) as CustomTestType<CustomTestArgs & WPTestArgs, CustomWorkerArgs>;

Motivation

Currently, there is no way to access custom test details inside hooks/custom fixtures. A built-in testInfo.details() method will provide access CustomTestDetails for such scenario and would streamline such processes.

MrVerifit avatar Dec 03 '24 21:12 MrVerifit

Hi Hassan! I'm pretty sure there's an existing feature inside Playwright you can use to achieve what you're looking for. Could you elaborate on what you're trying to achieve?

Skn0tt avatar Dec 03 '24 22:12 Skn0tt

Hi! Thanks for your response. I'm looking for a way to access custom properties defined in the TestDetails object directly within TestInfo during the execution of a test.

For example, if I define a test like this:

test("My Test", { envs: [{ plugin: "pro" }], resetDatabase: true }, async ({ page }, testInfo) => {
  const details = testInfo.details(); // Hypothetical method
  console.log(details.envs); // Expected output: [{ plugin: "pro" }]
  console.log(details.resetDatabase); // Expected output: true
});

Currently, there's no straightforward way to access the (Custom) TestDetails through TestInfo, which will be helpful to inject these information directly inside custom test hooks and custom test fixtures.

My goal is to have a built-in method (e.g., testInfo.details()) to access the TestDetails directly. This would allow:

Access Inside Custom Fixtures: Being able to leverage these details when setting up or tearing down fixtures. Access Inside Pre-Defined Test Hooks: For example, using the custom properties in hooks like beforeEach, afterEach, etc., to dynamically adjust behavior based on the test configuration. This feature would make custom test configurations more seamless and better integrated with Playwright's existing API.

Does Playwright already have a feature for this that I might have overlooked? I'd love to explore that if so!

Thank you! 😊

MrVerifit avatar Dec 04 '24 05:12 MrVerifit

Also I know something similar can be achieved using annotation:

test("basic test", { annotation: [{ type: 'env', description: '{ "plugin": "pro" }' }, { type: 'reset-database', description: 'skip' }] }, async ({ page, context }) => {})

But with my requested feature, it will be easier to write it concisely and make it more readable!

test("basic test", { env: [{ plugin: "pro" }], database: { reset: false } }, async ({ page, context }) => {})

MrVerifit avatar Dec 04 '24 06:12 MrVerifit

I think option fixtures are exactly what you need: https://playwright.dev/docs/test-fixtures#fixtures-options Let me know if that helps!

Skn0tt avatar Dec 04 '24 19:12 Skn0tt

I'd vote for @MrVerifit proposal. Option fixtures are not bound to the particular test. And they are defined far from the test itself, that makes it difficult to figure out which options are actually applied to the test.

I think, if there were per-test-fixtures implemented (see https://github.com/microsoft/playwright/issues/27138), then fixture options would be a solution, because it would be possible to write:

test("basic test", async ({ page, context }) => {
  // ...
}).use({
  database: [{ reset: false }, { option: true }]
});

For now, the workaround from the mentioned ticket should also work (although I personally not a fan of anonymous describe block):

test.describe(() => {
  test.use({ database: [{ reset: false }, { option: true }] });
  test('basic test', async ({ page }) => {
    // ...
  });
});

vitalets avatar Dec 06 '24 11:12 vitalets

Why was this issue closed?

Thank you for your involvement. This issue was closed due to limited engagement (upvotes/activity), lack of recent activity, and insufficient actionability. To maintain a manageable database, we prioritize issues based on these factors.

If you disagree with this closure, please open a new issue and reference this one. More support or clarity on its necessity may prompt a review. Your understanding and cooperation are appreciated.

pavelfeldman avatar Sep 04 '25 01:09 pavelfeldman