Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
MrVerifit opened this issue Dec 3, 2024 · 5 comments

Comments

@MrVerifit
Copy link

🚀 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.

@Skn0tt
Copy link
Member

Skn0tt commented Dec 3, 2024

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?

@MrVerifit
Copy link
Author

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
Copy link
Author

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 }) => {})

@Skn0tt
Copy link
Member

Skn0tt commented Dec 4, 2024

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

@vitalets
Copy link
Contributor

vitalets commented Dec 6, 2024

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 #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 }) => {
    // ...
  });
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants