vitalets / playwright-bdd

BDD testing with Playwright runner
https://vitalets.github.io/playwright-bdd/
MIT License
226 stars 22 forks source link

Question: How can I set multiple playwright fixtures without duplication steps? #160

Open bandriychuk opened 4 weeks ago

bandriychuk commented 4 weeks ago

How can I set multiple playwright fixtures without duplication steps:

Case: I have one step for verifications functionality where I provide data using dataTable.

I'd like to verify functionality under AdminUser and user with specific permissions.

Code Examples:

AdminUser

import {loggedAsAdminUser} from "../../../fixtures/baseTest";

const {When, Then} = createBdd(loggedAsAdminUser);

Then(/^I see AccountPage is (displayed|not displayed)$/, async ({app}, functionality: FunctionalityDataTable) => {
    await app functionalityPage.availableFunctionality(functionality);
});

UserWithCustomPermissions


import {loggedAsUserWithCustomPermissions} from "../../../fixtures/baseTest";

const {When, Then} = createBdd(loggedAsUserWithCustomPermissions);

Then(/^I see AccountPage is (displayed|not displayed)$/, async ({app}, functionality: FunctionalityDataTable) => {
    await app functionalityPage.availableFunctionality(functionality);
});

How can I reuse step with providing just specific playwright fixtures?
leimer commented 3 weeks ago

Hi @bandriychuk, not sure if this helps, but playwright offers a mechanism to merge fixtures together. https://playwright.dev/docs/test-fixtures#combine-custom-fixtures-from-multiple-modules

fixtures.ts

import { mergeTests } from '@playwright/test';
import { test as dbTest } from 'database-test-utils';
import { test as a11yTest } from 'a11y-test-utils';

export const test = mergeTests(dbTest, a11yTest);

test.spec.ts

import { test } from './fixtures';

test('passes', async ({ database, page, a11y }) => {
  // use database and a11y fixtures.
});

Make sure to handle your custom fixture properly. See documentation: https://vitalets.github.io/playwright-bdd/#/writing-steps/playwright-style?id=fixtures

vitalets commented 2 weeks ago

Step itself binds fixtures statically, as well as regular Playwright tests. If you want single step to handle different fixtures, you can achieve it via intermediate fixture:

export const test = base.extend({
  user: async ({ adminFixture, userFixture }, use) => {
    const user = isAdmin() ? adminFixture : userFixture;
    await use(user);
  }
});

// step
Then(/^check profile$/, async ({ user }) => {
  // user can be either admin or regular user
});

The downside is that both fixtures will be initialized for user-related and admin-related tests, that may have performance impact.