Rayrun
← Back to Discord Forum

Authentication with Cucumber using JS

Hi, I am using Cucumber with Javascript on Playwright (also integrated with Lambda). I am trying to add authentication but am unsure where and how to put it in the structure (hooks, page, or a separate js file?)

Do you have any idea? Thank you very much!

This thread is trying to answer question "How to implement authentication in Cucumber using Javascript on Playwright, using different JSON files for different roles?"

14 replies

You could use globalsetup if you are trying to reuse auth

But she means the framework of cucumber? I would also like to log in using Storage State. How do I do that with Cucumber, specifically with this framework cucumber playwright??

@tallyb ?

I would like to log in using Storage State, using different JSON files for different roles, such as one JSON for an admin, the second JSON for a team leader, and so on

Do you mean with playwright without cucumber? Like https://playwright.dev/docs/auth? But how do we implement this in cucumber for the repo of Tallyb??

you can use a before hook or you can specify it in a step, depends on your need.

@tallyb Do you mean a before hook like so a admin json will be load , and I can add another one for teamlead : Before(async function (this: ICustomWorld, { pickle }: ITestCaseHookParameter) { this.startTime = new Date(); this.testName = pickle.name.replace(/\W/g, '-');

// Load the storage state from the file const storageState = JSON.parse( await fs.readFile( 'C:/Users/Client/cucumber-playwright/src/auth/Admin.json', 'utf-8', ), );

but then you need to send it to the context.setStorage

yes that what I am doing: I add a step to my existing test cases. This step would allow me to log in as an admin using StorageState JSON, eliminating the need to enter login details every time. I also want to add another step to log in as a team lead using StorageState JSON, and another one to log in as a user using StorageState JSON. In this step, the following should occur: If no JSON file for the desired user exists, it is created. This is done by logging in with regular login details and storing the JSON. If the necessary JSON file exists, it is used. If the JSON file is no longer valid, it is recreated.

/* eslint-disable indent / / eslint-disable prettier/prettier */ // eslint-disable-next-line import/no-unresolved import { ICustomWorld } from '../support/custom-world'; import { Given } from '@cucumber/cucumber'; import { existsSync, readFileSync } from 'fs';

Given('the user logged in as an admin', async function (this: ICustomWorld) { const url = 'https://practice.automationtesting.in/my-account/'; const authFile = 'playwright/.auth/admin.json'; let storageState;

// Check if the JSON file exists and is not empty if (existsSync(authFile)) { try { const fileContent = readFileSync(authFile, 'utf-8').trim(); if (fileContent !== '') { storageState = JSON.parse(fileContent); } } catch (error) { console.error('Error reading or parsing the JSON file:', error); } }

if (storageState) { // Restore state await this.setStorageState(authFile); } else { // Sign in await this.page?.goto(url); await this.loginPage?.login('xxxx@xxx.com', 'Test1234567'); // Save the StorageState await this.saveStorageState(authFile); await this.page?.waitForLoadState('load'); } });

// In Custom-world I have saveStorageState and setStorageState methods: async saveStorageState(path: string) { if (this.context) { const storage = await this.context.storageState(); await fs.writeFile(path, JSON.stringify(storage)); } }

async setStorageState(path: string) { if (this.context) { const storageState = JSON.parse(await fs.readFile(path, 'utf-8')); this.context = await this.browser.newContext({ storageState, // Use the storageState here acceptDownloads: true, recordVideo: process.env.PWVIDEO ? { dir: 'screenshots' } : undefined, viewport: { width: 1200, height: 800 }, }); } }

// And in Common-hooks in the "before" I will use the storageState Before(async function (this: ICustomWorld, { pickle }: ITestCaseHookParameter) { this.startTime = new Date(); this.testName = pickle.name.replace(/\W/g, '-'); const storageState = JSON.parse(await fs.readFile('playwright/.auth/admin.json', 'utf-8')); this.context = await browser.newContext({ storageState, // Use the storageState here acceptDownloads: true, recordVideo: process.env.PWVIDEO ? { dir: 'screenshots' } : undefined, viewport: { width: 1200, height: 800 }, }); });

Is this the right approach? because I want to run later admin,teamlead und user storageState JSON in parallel, will this be defined in before hooks? and how??

you do not have access to customWorld in before, so this will not work.

Thank you and Iwould be pleased to receive more information and how I can manage my storage state with multiple different users. And I asked the same question in stack overflow but still no answer there: https://stackoverflow.com/questions/76587815/using-storagestate-json-of-different-userse-g-admin-teamlead-with-playwright

Related Discord Threads

TwitterGitHubLinkedIn
AboutQuestionsDiscord ForumBrowser ExtensionTagsQA Jobs

Rayrun is a community for QA engineers. I am constantly looking for new ways to add value to people learning Playwright and other browser automation frameworks. If you have feedback, email luc@ray.run.