This guide explains how to integrate:
- Playwright
- BDD (Behavior Driven Development)
- Cucumber
- Page Object Model (POM)
using JavaScript/TypeScript.
The framework structure will support:
- Readable feature files
- Reusable page objects
- Clean step definitions
- Scalable automation framework
- HTML reports
- Cross-browser execution
1. What You Will Build
You will create a framework like this:
PlaywrightBDDFramework/
│
├── features/
│ ├── login.feature
│ └── step-definitions/
│ └── login.steps.ts
│
├── pages/
│ └── LoginPage.ts
│
├── hooks/
│ └── hooks.ts
│
├── utils/
│ └── helper.ts
│
├── reports/
│
├── playwright.config.ts
├── cucumber.js
├── package.json
└── tsconfig.json
2. Install Node.js
Install Node.js from:
Verify installation:
node -v
npm -v
3. Create Project
mkdir PlaywrightBDDFramework
cd PlaywrightBDDFramework
Initialize project:
npm init -y
4. Install Required Dependencies
Install Playwright
npm install -D @playwright/test
Install browsers:
npx playwright install
Install Cucumber + TypeScript Support
npm install -D @cucumber/cucumber
npm install -D typescript ts-node
npm install -D @types/node
Install Reporting Packages
npm install -D multiple-cucumber-html-reporter
npm install -D cucumber-html-reporter
5. Configure TypeScript
Create:
tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"types": ["node"],
"strict": false,
"esModuleInterop": true,
"skipLibCheck": true
}
}
6. Configure Cucumber
Create:
cucumber.js
module.exports = {
default: {
require: [
"features/step-definitions/*.ts",
"hooks/*.ts"
],
format: [
"progress",
"json:reports/cucumber-report.json"
],
requireModule: ["ts-node/register"],
paths: ["features/*.feature"]
}
};
7. Create Playwright Config
playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
testDir: './features',
timeout: 60000,
use: {
headless: false,
screenshot: 'only-on-failure',
video: 'retain-on-failure'
}
});
8. Create Feature File
features/login.feature
Feature: Login Functionality
Scenario: Successful Login
Given User launches the application
When User enters username and password
And User clicks on login button
Then User should navigate to dashboard
9. Create Page Object Model (POM)
pages/LoginPage.ts
import { Page } from '@playwright/test';
export class LoginPage {
constructor(private page: Page) {}
username = '#username';
password = '#password';
loginBtn = '#loginBtn';
async launchApplication() {
await this.page.goto('https://example.com');
}
async enterUsername(username: string) {
await this.page.fill(this.username, username);
}
async enterPassword(password: string) {
await this.page.fill(this.password, password);
}
async clickLogin() {
await this.page.click(this.loginBtn);
}
}
10. Create Hooks File
Hooks help initialize browser and cleanup.
hooks/hooks.ts
import {
Before,
After,
BeforeAll,
AfterAll
} from '@cucumber/cucumber';
import { chromium, Browser, Page } from '@playwright/test';
let browser: Browser;
let page: Page;
BeforeAll(async () => {
browser = await chromium.launch({
headless: false
});
});
Before(async function () {
const context = await browser.newContext();
page = await context.newPage();
this.page = page;
});
After(async function () {
await page.close();
});
AfterAll(async () => {
await browser.close();
});
11. Create Step Definitions
features/step-definitions/login.steps.ts
import { Given, When, Then } from '@cucumber/cucumber';
import { expect } from '@playwright/test';
import { LoginPage } from '../../pages/LoginPage';
let loginPage: LoginPage;
Given('User launches the application', async function () {
loginPage = new LoginPage(this.page);
await loginPage.launchApplication();
});
When('User enters username and password', async function () {
await loginPage.enterUsername('admin');
await loginPage.enterPassword('admin123');
});
When('User clicks on login button', async function () {
await loginPage.clickLogin();
});
Then('User should navigate to dashboard', async function () {
await expect(this.page).toHaveURL(/dashboard/);
});
12. Add Scripts in package.json
Update:
package.json
"scripts": {
"test": "cucumber-js",
"test:headed": "cucumber-js --tags '@SmokeTest'",
"report": "node report.js"
}
13. Execute Tests
Run:
npm test
14. Generate HTML Reports
Create:
report.js
const report = require('multiple-cucumber-html-reporter');
report.generate({
jsonDir: 'reports',
reportPath: 'reports/html-report',
metadata: {
browser: {
name: 'chrome',
version: 'latest'
},
device: 'Local Machine',
platform: {
name: 'windows',
version: '11'
}
}
});
Run:
node report.js
15. Add Tags in Feature Files
@SmokeTest
Feature: Login Functionality
Run specific tags:
npx cucumber-js --tags "@SmokeTest"
16. Add Environment Support
Create:
.env
BASE_URL=https://example.com
USERNAME=admin
PASSWORD=admin123
Install dotenv:
npm install dotenv
Use:
import dotenv from 'dotenv';
dotenv.config();
process.env.BASE_URL
17. Best Framework Structure
framework/
│
├── features/
├── pages/
├── hooks/
├── utils/
├── locators/
├── test-data/
├── reports/
├── screenshots/
├── videos/
├── logs/
└── config/
18. Advanced Improvements
You can enhance the framework with:
| Feature | Benefit |
|---|---|
| Parallel Execution | Faster execution |
| CI/CD Integration | Automated pipeline |
| Retry Logic | Stable execution |
| API + UI Framework | Hybrid testing |
| Docker Support | Easy setup |
| Allure Reports | Better reporting |
| Faker Data | Dynamic test data |
| Database Validation | End-to-end validation |
19. Real-Time Industry Best Practices
Use Separate Layers
Page Layer
- Locators
- Page actions
Step Definition Layer
- BDD mapping only
Utility Layer
- Reusable functions
Test Data Layer
- JSON/CSV/Excel data
20. Recommended Design Pattern
Hybrid Framework
Combine:
- POM
- BDD
- Data-Driven
- Utility Helpers
- API Helpers
- Reporting
- CI/CD
21. Sample Execution Flow
Feature File
↓
Step Definition
↓
Page Object
↓
Playwright Actions
↓
Browser Execution
22. Advantages of BDD with POM
| BDD | POM |
|---|---|
| Readable scenarios | Reusable code |
| Business friendly | Maintainable |
| Better collaboration | Easy scaling |
| Easy reporting | Cleaner structure |
23. Common Interview Questions
What is BDD?
BDD is a development approach where application behavior is written in simple language using Gherkin syntax.
Why use POM?
POM improves:
- Reusability
- Maintainability
- Scalability
Difference Between Playwright Test and Cucumber?
| Playwright Test | Cucumber |
|---|---|
| Technical | Business readable |
| Fast execution | BDD support |
| Built-in fixtures | Gherkin support |
24. Recommended Learning Path
- Playwright Basics
- TypeScript Fundamentals
- POM Design
- BDD Concepts
- Cucumber Framework
- Reporting
- CI/CD
- Docker
- API Automation
- AI-assisted Automation