[Feature]: Ability to access custom TestDetails through TestInfo directly inside TestHook!
🚀 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.
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?
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! 😊
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 }) => {})
I think option fixtures are exactly what you need: https://playwright.dev/docs/test-fixtures#fixtures-options Let me know if that helps!
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 }) => {
// ...
});
});
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.