vitalets / playwright-bdd

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

Question: Possible add auth setup ? #130

Closed synnksou closed 5 months ago

synnksou commented 5 months ago

Is it possible to set up tests, for example, for the authentication of the app?

Because it doesn't generate tests with the playwright UI if we use {name: "setup", testMatch: "setup.ts"} on playwright.setup.ts.

Also, is it possible to perform a setup before all the tests each time without rewriting it in each step file?

Thank you in advance.

vitalets commented 5 months ago

It should work. Could you share full Playwright config?

Also, is it possible to perform a setup before all the tests each time without rewriting it in each step file?

Could you provide an example with more details?

synnksou commented 5 months ago

Here's an example of configuration with a setup, I've just used the basic Playwright setup, in fact tests are not generated on the Playwright UI side with a Setup in the playwright.config.ts file, but he passed on playwright test command

auth.setup.ts file

import { test as setup, expect } from '@playwright/test';

const authFile = 'user.json';

setup('authenticate', async ({ page }) => {
  // Perform authentication steps. Replace these actions with your own.
  await page.goto('https://github.com/login');
  await page.getByLabel('Username or email address').fill('myemail');
  await page.getByLabel('Password').fill('password');
  await page.getByRole('button', { name: 'Sign in' }).click();
  // Wait until the page receives the cookies.
  //
  // Sometimes login flow sets cookies in the process of several redirects.
  // Wait for the final URL to ensure that the cookies are actually set.
  await page.waitForURL('https://github.com/');
  // Alternatively, you can wait until the page reaches a state where all cookies are set.
  await expect(
    page.getByRole('button', { name: 'View profile and more' }),
  ).toBeVisible();

  // End of authentication steps.

  await page.context().storageState({ path: authFile });
});

playwright.config.ts

import { defineConfig, devices } from '@playwright/test';
import { defineBddConfig, cucumberReporter } from 'playwright-bdd';

const testDir = defineBddConfig({
  paths: ['features/*.feature'],
  require: ['steps/*.ts'],
  importTestFrom: 'steps/fixtures.ts',
});

export default defineConfig({
  testDir,
  reporter: [
    cucumberReporter('html', { outputFile: 'cucumber-report/report.html' }),
  ],
  projects: [
    { name: 'setup', testMatch: /.*\.setup\.ts/ },
    {
      name: 'chromium',
      use: {
        ...devices['Desktop Chrome'],
        storageState: 'user.json',
      },
      dependencies: ['setup'],
    },
  ],
});

UI Playwright screenshot ("npx bddgen && npx playwright test --ui" or "playwright test --ui"): image Playwright test passed no UI image

vitalets commented 5 months ago

Figured out the problem. When testDir is defined on the top level of the config, it is shared between all projects. But setup project files are not in .feature-gen. The solution is to define testDir for setup project:

projects: [
    { 
        name: 'setup', 
        testMatch: /.*\.setup\.ts/,
        testDir: './setup' // <-- set dir for setup specs
    },

Could you check and let me know, does it help? I'd add this case to the docs, as it is very popular setup.

vitalets commented 5 months ago

Added Authentication project in docs.

synnksou commented 5 months ago

Figured out the problem. When testDir is defined on the top level of the config, it is shared between all projects. But setup project files are not in .feature-gen. The solution is to define testDir for setup project:

projects: [
    { 
        name: 'setup', 
        testMatch: /.*\.setup\.ts/,
        testDir: './setup' // <-- set dir for setup specs
    },

Could you check and let me know, does it help? I'd add this case to the docs, as it is very popular setup.

Yes i try this today

synnksou commented 5 months ago

Not working for me in playwright UI on setup filter with the testDir: './setup' // <-- set dir for setup specs on setup file, i try to add this on testDir of defineConfig, same with error

vitalets commented 5 months ago

Could you please create a repro branch based on playwright-bdd-example?

synnksou commented 5 months ago

Sorry I didn't have time before, I'm doing this today ! :)

synnksou commented 5 months ago

Could you please create a repro branch based on playwright-bdd-example?

I don't have the acces to push branch for based on ur repo

vitalets commented 5 months ago

@synnksou You should fork the playwright-bdd-example repo first. Sorry for unclear instructions, updated the README.

QAPranav commented 5 months ago

Hey @vitalets and @synnksou I found some way out we can also convert the user.json file to arrary in run time and pass to the page context its working fine for me so first this will run auth file and convert the json file to array pass to context before opening page here is the code if this helps Given('I navigate to {string}', async ({ ecomLoginPage, page }, url) => { const cookies = require('../../../playwright/.auth/user.json') const cookiesArray = cookies.cookies; await page.context().addCookies(cookiesArray) await ecomLoginPage.navigateToUrl(url); }); As we just need a cookies array from user.json file { "cookies": [ { "name": "OCSESSID", "value": "70f503afd6660f1fa63569fab1", "domain": "ecommerce-playground.lambdatest.io", "path": "/", "expires": -1, "httpOnly": false, "secure": false, "sameSite": "Lax" }, { "name": "language", "value": "en-gb", "domain": ".ecommerce-playground.lambdatest.io", "path": "/", "expires": 1715798939.874418, "httpOnly": false, "secure": false, "sameSite": "Lax" }, { "name": "currency", "value": "USD", "domain": ".ecommerce-playground.lambdatest.io", "path": "/", "expires": 1715798939.874489, "httpOnly": false, "secure": false, "sameSite": "Lax" } ], "origins": [] }

vitalets commented 5 months ago

Interesting! I didn't know about page.context().addCookies() method.

synnksou commented 5 months ago

@vitalets Sorry for my late reply, I'll look at it on Friday for the fork,

Hey @vitalets and @synnksou I found some way out we can also convert the user.json file to arrary in run time and pass to the page context its working fine for me so first this will run auth file and convert the json file to array pass to context before opening page here is the code if this helps Given('I navigate to {string}', async ({ ecomLoginPage, page }, url) => { const cookies = require('../../../playwright/.auth/user.json') const cookiesArray = cookies.cookies; await page.context().addCookies(cookiesArray) await ecomLoginPage.navigateToUrl(url); }); As we just need a cookies array from user.json file { "cookies": [ { "name": "OCSESSID", "value": "70f503afd6660f1fa63569fab1", "domain": "ecommerce-playground.lambdatest.io", "path": "/", "expires": -1, "httpOnly": false, "secure": false, "sameSite": "Lax" }, { "name": "language", "value": "en-gb", "domain": ".ecommerce-playground.lambdatest.io", "path": "/", "expires": 1715798939.874418, "httpOnly": false, "secure": false, "sameSite": "Lax" }, { "name": "currency", "value": "USD", "domain": ".ecommerce-playground.lambdatest.io", "path": "/", "expires": 1715798939.874489, "httpOnly": false, "secure": false, "sameSite": "Lax" } ], "origins": [] }

It's interesting, maybe use Cucumber's tags in the Gherkin, as far as I'm concerned it works on my pro project but I have the impression that I don't have much control over them, whereas the playwright setup gives me that control.

synnksou commented 5 months ago

@vitalets I close the question, setup work perfectly on 6.3.0