1

This is my fixture file: I try for signup new user here

import { test as baseTest, request } from '@playwright/test';
import SignUp from '../pages/SignUp';
import fs from 'fs';
import path from 'path';

export * from '@playwright/test';
export const test = baseTest.extend<{}, { workerStorageState: string }>({
    // Use the same storage state for all tests in this worker.
    storageState: ({ workerStorageState }, use) => use(workerStorageState),

    // Authenticate once per worker with a worker-scoped fixture.
    workerStorageState: [
        async ({ browser }, use) => {
            // Use parallelIndex as a unique identifier for each worker.
            const id = test.info().parallelIndex;
            const fileName = path.resolve(test.info().project.outputDir, `.auth/${id}.json`);

            if (fs.existsSync(fileName)) {
                // Reuse existing authentication state if any.
                await use(fileName);
                return;
            }

            // Important: make sure we authenticate in a clean environment by unsetting storage state.
            const context = await request.newContext({ storageState: undefined });
            const page = await browser.newPage({ storageState: undefined });
            // Create fake data for a user and signUp
            const signUp = new SignUp(page);
            // SignUp a new user
            await signUp.SignUp();

            await context.storageState({ path: fileName });
            await page.context().storageState({ path: fileName });
            await context.dispose();
            await page.close();
            await use(fileName);
        },
        { scope: 'worker' },
    ],
});

This is my playwright.config.ts file:

// @ts-check
import { defineConfig, devices } from '@playwright/test';

/**
 * Read environment variables from file.
 * https://github.com/motdotla/dotenv
 */
require('dotenv').config();

/**
 * @see https://playwright.dev/docs/test-configuration
 */
module.exports = defineConfig({
    testDir: './e2e',
    /* Run tests in files in parallel */
    timeout: 90000,
    expect: {
        timeout: 60000,
    },
    fullyParallel: true,
    /* Fail the build on CI if you accidentally left test.only in the source code. */
    forbidOnly: !!process.env.CI,
    /* Retry on CI only */
    retries: process.env.CI ? 2 : 0,
    /* Opt out of parallel tests on CI. */
    workers: process.env.CI ? 1 : undefined,
    /* Reporter to use. See https://playwright.dev/docs/test-reporters */
    reporter: 'html',
    /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
    use: {
        /* Base URL to use in actions like `await page.goto('/')`. */
        baseURL: process.env.VITE_APP_HOST,

        video: 'on',

        /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
        trace: 'on-first-retry',
    },

    /* Configure projects for major browsers */
    projects: [
        // Setup project
        {
            name: 'chromium',
            use: {
                ...devices['Desktop Chrome'],
            },
        },

        
    ],

    /* Run your local dev server before starting the tests */
    // webServer: {
    //   command: 'npm run start',
    //   url: 'http://127.0.0.1:3000',
    //   reuseExistingServer: !process.env.CI,
    // },
});

And this is one of my tests: I have tried to login in beforEach

// @ts-check
import { test } from '../../playwright/fixtures';
import Products from '../../pages/ProductAndServices/Products';
import Quotes from '../../pages/Quotes/Quotes';
import LoginPage from '../../pages/LoginPage';
import SignUp from '../../pages/SignUp';

test.describe('Create new product', async () => {
    let userData: { email: string; password: string; familyName: string; givenName: string; organizationName: string; phoneNumber: string };
    let loginPage: LoginPage;
    let signUp: SignUp;
    let products: Products;
    let quotes: Quotes;
    test.beforeEach(async ({ page }) => {
        loginPage = new LoginPage(page);
        signUp = new SignUp(page);
        products = new Products(page);
        quotes = new Quotes(page);
        userData = signUp.userData();
        await loginPage.Login(userData.email, userData.password);
    });

    test('Create product from Product & Services', async () => {
        await products.OpenProductsPage();
        await products.OpenNewProduct();
        await products.EnterProductName();
        await products.EnterProductDescription();
        await products.CreateNewCategory();
        await products.SelctNewCategory();
        await products.AddPurchacePrice();
        await products.AddSellingPrice();
        await products.SaveProduct();
        await products.CheckCreatedProduct();
    });
});

When I run npx playwright test, some tests will fail in login because of invalid credentials. (test uses credentials of another test). How can I update my fixtures.ts file to signup by a new user for each test on each worker?

Thank you in advance for your help.

1 Answers1

1

I changed fixtures to this and problem solved:

import { test as baseTest, BrowserContextOptions } from '@playwright/test';
import SignUp from '../pages/SignUp';
import fs from 'fs';
import path from 'path';

export * from '@playwright/test';
export const test = baseTest.extend<{}, { workerStorageState: string }>({
    // Use the same storage state for all tests in this worker.
    storageState: ({ workerStorageState }, use) => use(workerStorageState),

    // Authenticate once per test with a test-scoped fixture.
    workerStorageState: [
        async ({ browser }, use) => {
            // Use parallelIndex as a unique identifier for each worker.
            const id = test.info().parallelIndex;
            const fileName = path.resolve(test.info().project.outputDir, `.auth/${id}.json`);

            const contextOptions: BrowserContextOptions = {
                storageState: undefined,
            };
            // Important: make sure we authenticate in a clean environment by unsetting storage state.
            const context = await browser.newContext(contextOptions);
            const page = await context.newPage();

            // Create fake data for a user and signUp
            const signUp = new SignUp(page);
            // SignUp a new user
            await signUp.SignUp();

            // Save the new storage state for this test.
            await context.storageState({ path: fileName });

            await page.close();
            await context.close();
            await use(fileName);
        },
        { scope: 'worker' },
    ],
});