As Playwright automation frameworks grow, applying design patterns helps improve maintainability, scalability, reusability, and test readability. These patterns are commonly discussed in interviews for Senior SDET, Automation Architect, and QA Lead roles.
Why Use Design Patterns?
Without design patterns, automation frameworks often suffer from:
- Duplicate code
- Tight coupling
- Difficult maintenance
- Large Page Objects
- Hardcoded logic
- Poor scalability
Using design patterns helps create frameworks that are easier to extend and maintain.
1. Factory Pattern
What is Factory Pattern?
The Factory Pattern centralizes object creation instead of allowing tests to instantiate classes directly.
Instead of:
const loginPage = new LoginPage(page);
const dashboardPage = new DashboardPage(page);
const cartPage = new CartPage(page);
Create objects through a factory.
Why Use Factory Pattern?
Benefits
- Centralized object creation
- Easier maintenance
- Supports Dependency Injection
- Simplifies test code
- Reduces duplicate initialization
Architecture
Test
│
▼
Page Factory
┌──────┼──────┐
▼ ▼ ▼
LoginPage Dashboard CartPage
Example Implementation
LoginPage
import { Page } from '@playwright/test';
export class LoginPage {
constructor(private readonly page: Page) {}
async login(username: string, password: string) {
// Login steps
}
}
DashboardPage
import { Page } from '@playwright/test';
export class DashboardPage {
constructor(private readonly page: Page) {}
async verifyDashboard() {
// Verification logic
}
}
PageFactory
import { Page } from '@playwright/test';
import { LoginPage } from '../pages/LoginPage';
import { DashboardPage } from '../pages/DashboardPage';
export class PageFactory {
constructor(private readonly page: Page) {}
get loginPage() {
return new LoginPage(this.page);
}
get dashboardPage() {
return new DashboardPage(this.page);
}
}
Usage
const factory = new PageFactory(page);
await factory.loginPage.login(username, password);
await factory.dashboardPage.verifyDashboard();
Advantages
✔ Cleaner tests
✔ Centralized object creation
✔ Easy maintenance
✔ Supports Dependency Injection
✔ Easily extendable
Disadvantages
- Slightly more abstraction
- May be unnecessary for very small projects
Factory Pattern Interview Questions
Q1. Why use the Factory Pattern?
Answer
To centralize object creation, reduce duplicate initialization, improve maintainability, and simplify test code.
Q2. When should you avoid the Factory Pattern?
Answer
For very small frameworks with only a few page objects, a factory may add unnecessary complexity.
2. Builder Pattern
What is Builder Pattern?
The Builder Pattern creates complex objects step by step.
Instead of creating long constructors:
const user = {
username: "admin",
password: "pass",
role: "Manager",
department: "QA",
active: true
};
Use a builder.
Why Use Builder Pattern?
Benefits
- Readable object creation
- Optional fields
- Fluent API
- Easier maintenance
- Less constructor complexity
Example Architecture
User Builder
│
▼
Build User Object
│
▼
Test Uses Object
Example
User Model
export interface User {
username: string;
password: string;
role: string;
department: string;
}
Builder
export class UserBuilder {
private user = {
username: "",
password: "",
role: "",
department: ""
};
withUsername(username: string) {
this.user.username = username;
return this;
}
withPassword(password: string) {
this.user.password = password;
return this;
}
withRole(role: string) {
this.user.role = role;
return this;
}
withDepartment(department: string) {
this.user.department = department;
return this;
}
build() {
return this.user;
}
}
Usage
const user = new UserBuilder()
.withUsername("admin")
.withPassword("admin123")
.withRole("Manager")
.withDepartment("QA")
.build();
Benefits
- Fluent syntax
- Easy to read
- Easy to extend
- Avoids large constructors
- Great for test data creation
Real Playwright Use Cases
Builder Pattern is useful for creating:
- Test users
- Customer objects
- Orders
- Payment requests
- API payloads
- Product data
- Registration forms
Builder Pattern Interview Questions
Q1. Why use Builder instead of constructors?
Answer
Builders improve readability, support optional fields, and prevent constructors with many parameters that are difficult to understand and maintain.
Q2. Where is Builder commonly used in automation?
Answer
Creating complex test data, API payloads, registration forms, and domain objects used across tests.
3. Strategy Pattern
What is Strategy Pattern?
The Strategy Pattern allows you to switch algorithms or behaviors at runtime without changing the client code.
Instead of writing:
if(browser === "chrome") {
}
else if(browser === "firefox") {
}
else if(browser === "webkit") {
}
Move each behavior into its own strategy.
Why Use Strategy Pattern?
Benefits
- Easy to add new behavior
- No large if-else chains
- Better maintainability
- Open for extension
- Easier unit testing
Architecture
Test
│
▼
Browser Strategy
┌─────┼─────┐
▼ ▼ ▼
Chrome Firefox WebKit
Example
Interface
export interface BrowserStrategy {
launch(): Promise<void>;
}
Chrome Strategy
export class ChromiumStrategy implements BrowserStrategy {
async launch() {
console.log("Launch Chromium");
}
}
Firefox Strategy
export class FirefoxStrategy implements BrowserStrategy {
async launch() {
console.log("Launch Firefox");
}
}
Context
export class BrowserLauncher {
constructor(private strategy: BrowserStrategy) {}
async start() {
await this.strategy.launch();
}
}
Usage
const launcher = new BrowserLauncher(
new ChromiumStrategy()
);
await launcher.start();
Playwright Use Cases
Strategy Pattern is useful for:
- Browser selection
- Authentication methods
- Environment-specific behavior
- Payment gateway flows
- Report generation
- File upload mechanisms
- Different login types (UI, API, SSO)
Authentication Example
Login
│
┌────────┼────────┐
▼ ▼ ▼
UI Login API Login SSO Login
The test selects the appropriate authentication strategy without changing its own logic.
Report Generation Example
Report Strategy
│
┌─────┼──────┐
▼ ▼ ▼
HTML Allure JUnit
Advantages of Strategy Pattern
✔ Removes large conditional statements
✔ Supports Open/Closed Principle
✔ Easy to extend
✔ Highly testable
✔ Easy maintenance
Factory vs Builder vs Strategy
| Feature | Factory | Builder | Strategy |
|---|---|---|---|
| Main Purpose | Create objects | Construct complex objects | Change behavior dynamically |
| Focus | Object creation | Object configuration | Algorithm/behavior selection |
| Returns | Ready-to-use objects | Configured object | Selected implementation |
| Typical Playwright Use | Page Objects, API clients | Test data, payloads | Browser, authentication, reporting |
| Supports Extensibility | Yes | Yes | Excellent |
Combining Patterns in a Playwright Framework
Enterprise frameworks often combine multiple patterns:
Test
│
▼
Workflow Layer
│
▼
Page Factory
│
┌────────────┼────────────┐
▼ ▼ ▼
LoginPage ProductPage CartPage
│
▼
Builder Objects
│
▼
Test Data Objects
│
▼
Strategy Selection
┌────────────┼────────────┐
▼ ▼ ▼
Browser Authentication Reporting
Real-World Example
Imagine an e-commerce application:
- Factory Pattern
- Creates
LoginPage,CartPage,CheckoutPage, andOrderPage.
- Creates
- Builder Pattern
- Creates customer profiles, shipping addresses, payment requests, and order payloads.
- Strategy Pattern
- Chooses:
- Browser (Chromium, Firefox, WebKit)
- Login method (UI, API, SSO)
- Payment method (Credit Card, PayPal, UPI)
- Report type (HTML, Allure)
- Chooses:
Together, these patterns produce a framework that is easier to maintain, easier to extend, and capable of supporting large-scale automation projects with minimal changes to existing code.
Senior SDET Interview Questions
1. Which design patterns have you used in your Playwright framework?
Answer:
I commonly use the Page Object Model, Factory Pattern for page object creation, Builder Pattern for test data and API payloads, Strategy Pattern for browser and authentication selection, Facade/Workflow Pattern for business processes, and Dependency Injection through Playwright fixtures.
2. Which design pattern is most useful in automation frameworks?
Answer:
There isn’t a single best pattern. Page Object Model is foundational, Factory simplifies object creation, Builder improves test data management, Strategy removes conditional logic, and Workflow (Facade) keeps business flows reusable. The best choice depends on the problem being solved.
3. How do these patterns improve maintainability?
Answer:
They separate responsibilities, reduce code duplication, isolate changes, improve readability, and make it easier to extend the framework without modifying existing test code. This aligns with SOLID principles and results in a more scalable automation architecture.