I am new to Playwright and I am trying to create a Cucumber Playwright POM framework. For this I have create 2 feature files userLogin.feature and bookHotel.feature. And I have 3 step definition files called userLogin.steps.js, bookHotel.steps.js and searchHotel.steps.js. When I run the userLogin.feature file alone, it works fine as I have only 3 steps mentioned in it. However, when I run bookHotel.feature file which reuses 3 steps from userLogin.steps.js and 1 step from searchHotel.steps.js. It gives error stating Page is Not defined in the searchHotel.steps.js file. I have tried various ways to initialise the page object but I am not able to fix the issue. Is there a way to utilise the same steps across multiple feature files like in cucumber java?
Issue:
Scenario: Booking Hotel scenario # features/bookHotel.feature:3
✔ Before # steps/userLogin.steps.js:11
✔ Given User navigate to the Hotel app # steps/userLogin.steps.js:21
✔ Then User should see the login page # steps/userLogin.steps.js:26
✔ Then User will login to the app # steps/userLogin.steps.js:34
✖ Then User will search for the hotel # steps/searchHotel.steps.js:6
ReferenceError: page is not defined
at World.<anonymous> (/Users/abcd/Documents/PlaywrightCucumberTraining/steps/searchHotel.steps.js:7:45)
✔ After # steps/userLogin.steps.js:17
1 scenario (1 failed)
4 steps (1 failed, 3 passed)
userLogin.feature
Feature: User Login feature
Scenario: User Login scenario
Given User navigate to the Hotel app
Then User should see the login page
Then User will login to the app
bookHotel.feature
Feature: Booking Hotel feature
Scenario: Booking Hotel scenario
Given User navigate to the Hotel app
Then User should see the login page
Then User will login to the app
Then User will search for the hotel
userLogin.steps.js:
const { Given, Then, Before, After, BeforeAll } = require('@cucumber/cucumber');
const { expect } = require('@playwright/test');
const { chromium } = require('playwright');
const LoginPage = require('../pages/login.page');
const SearchHotelPage = require('../pages/searchHotel.page');
const {searchHotelSelectors} = require('../data/testData.json');
require('dotenv').config();
let browser, context, page;
Before(async () => {
browser = await chromium.launch({ headless: false });
context = await browser.newContext();
page = await context.newPage();
});
After(async () => {
await browser.close();
});
Given('User navigate to the Hotel app', { timeout: 20000 }, async () => {
await page.goto(process.env.url);
});
Then('User should see the login page',{ timeout: 20000 }, async () => {
await expect(page.locator('text=XYZ Launches The XYZ Hotel App!')).toBeVisible();
const loginPage = new LoginPage(page);
await loginPage.login();
//await loginPageInstance.login();
});
Then('User will login to the app',{ timeout: 20000 }, async () => {
await expect(page.locator('text=Welcome to XYZ Group of Hotels')).toBeVisible();
});
// Then('User will search for the hotel',{ timeout: 20000 }, async () => {
// const searchHotelPage=new SearchHotePage(this.page);
// //console.log(testData.searchHotelDetails.location)
// await searchHotelPage.searchHotel(searchHotelSelectors.searchHotelDetails.location);
// });
searchHotel.steps.js
const { Given, Then, Before, After } = require('@cucumber/cucumber');
const SearchHotelPage = require('../pages/searchHotel.page');
const {searchHotelSelectors} = require('../data/testData.json');
require('dotenv').config();
Then('User will search for the hotel',{ timeout: 20000 }, async () => {
const searchHotelPage=new SearchHotelPage(page);
await searchHotelPage.searchHotel(searchHotelSelectors.searchHotelDetails.location);
});
login.page.js
const { expect } = require('@playwright/test');
const selectors = require('../pages/selectors/login.selectors');
require('dotenv').config();
class LoginPage {
constructor(page) {
this.page = page;
this.usernameInput = page.locator(selectors.usernameInput);
this.passwordInput = page.locator(selectors.passwordInput);
this.loginButton = page.locator(selectors.loginButton);
}
async login() {
await this.usernameInput.fill(process.env.username);
await this.passwordInput.fill(process.env.password);
await this.loginButton.click();
}
}
module.exports = LoginPage;
searchHotel.page.js
const selectors = require('../pages/selectors/searchHotel.selectors');
require('dotenv').config();
class SearchHotelPage {
constructor(page) {
//if (!page) throw new Error("Page is not defined");
this.page = page;
console.log("Page object initialized:", this.page);
//this.locationDropdown = page.getBy
this.locationDropdown = page.locator(selectors.locationDropdown);
this.hotelsDropdown = page.locator(selectors.hotelsDropdown);
this.adultsPerRoomDropdown = page.locator(selectors.adultsPerRoomDropdown);
this.searchButton = page.locator(selectors.searchButton);
}
async searchHotel(location) {
await this.locationDropdown.selectOption({ value: location});
}
}
module.exports = SearchHotelPage;