Introduction
The Playwright TypeScript Page Object Model is one of the most popular design patterns for building scalable automation frameworks. Whether you are an Automation Test Engineer, Selenium tester, or a beginner learning Playwright, understanding the Playwright Page Object Model is essential.
A well-designed Playwright TypeScript Framework keeps your automation code clean, reusable, and easy to maintain. Instead of writing locators in every test file, the Page Object Model (POM) stores them in dedicated page classes.
In this guide, you’ll learn how to implement Page Object Model in Playwright TypeScript, create an enterprise-ready framework, write reusable methods, and prepare for automation testing interviews.
What is Playwright?
Playwright is Microsoft’s modern open-source automation framework used for testing web applications.
It supports:
- Chromium
- Firefox
- WebKit
- Windows
- Linux
- macOS
Playwright provides:
- Auto waiting
- Fast execution
- Parallel testing
- Network interception
- Mobile emulation
- API testing
It has become a preferred replacement for Selenium in many organizations.
Why TypeScript with Playwright?
TypeScript adds strong typing to JavaScript.
Benefits include:
- Better IntelliSense
- Early error detection
- Cleaner code
- Easier maintenance
- Better developer productivity
Example:
let username: string = “admin”;
The compiler immediately reports incorrect data types before execution.
What is the Page Object Model (POM)?
The Playwright Page Object Model is a design pattern where every webpage is represented by a separate class.
Instead of writing:
await page.locator(“#username”).fill(“admin”);
inside every test, you create reusable methods.
Example:
Login Page
│
▼
LoginPage.ts
│
▼
login(username,password)
│
▼
Used by all tests
This reduces duplicate code and improves maintainability.
Why Use the Playwright TypeScript Page Object Model?
Advantages include:
- Cleaner tests
- Reusable methods
- Centralized locators
- Easy maintenance
- Faster framework updates
- Enterprise-ready architecture
- Improved readability
- Better collaboration among QA teams
Enterprise Playwright Framework Folder Structure
PlaywrightFramework
│
├── tests
│ login.spec.ts
│
├── pages
│ LoginPage.ts
│ DashboardPage.ts
│
├── fixtures
│ baseFixture.ts
│
├── utils
│ ReadData.ts
│
├── test-data
│ users.json
│
├── playwright.config.ts
│
└── package.json
This structure separates responsibilities and keeps the framework organized.
Creating the First Page Object (LoginPage.ts)
import { Page } from ‘@playwright/test’;
export class LoginPage {
constructor(private page: Page){}
username = this.page.locator(“#username”);
password = this.page.locator(“#password”);
loginButton = this.page.locator(“#login”);
async login(user:string,pass:string){
await this.username.fill(user);
await this.password.fill(pass);
await this.loginButton.click();
}
}
Step-by-Step Explanation
Import Page
import { Page } from ‘@playwright/test’;
Imports the Playwright Page class.
Constructor
constructor(private page: Page){}
Stores the current browser page for later use.
Username Locator
username = this.page.locator(“#username”);
Stores the username textbox locator.
Password Locator
password = this.page.locator(“#password”);
Stores the password textbox.
Login Button
loginButton = this.page.locator(“#login”);
Stores the login button locator.
Login Method
async login(user:string,pass:string){
Reusable login method.
Inside it:
await this.username.fill(user);
Enters username.
await this.password.fill(pass);
Enters password.
await this.loginButton.click();
Clicks Login.
Now every test can simply call:
await loginPage.login(“admin”,”admin123″);
Writing Test Scripts Using POM
import { test } from ‘@playwright/test’;
import { LoginPage } from ‘../pages/LoginPage’;
test(‘Login Test’, async ({ page }) => {
const loginPage = new LoginPage(page);
await page.goto(“https://example.com”);
await loginPage.login(“admin”,”admin123″);
});
Explanation
- Creates LoginPage object
- Opens application
- Calls reusable login method
- Keeps test readable
Reusable Methods
Instead of writing locators repeatedly:
async enterUsername(username:string){
await this.username.fill(username);
}
Similarly:
async enterPassword(password:string){
await this.password.fill(password);
}
Now methods can be reused across hundreds of tests.
Working with Playwright Locators
Examples:
page.locator(“#email”)
ID locator
page.locator(“.login”)
Class locator
page.getByRole(‘button’,{name:’Login’})
Role locator
page.getByText(“Logout”)
Text locator
Best practice is to use semantic locators like getByRole() or stable test IDs when available.
Using Fixtures
Fixtures help reduce duplicate setup code.
Example:
import { test as base } from ‘@playwright/test’;
export const test = base.extend({
});
Fixtures can initialize:
- Login
- Browser
- Test data
- Database
- API authentication
This makes the Playwright Automation Framework more scalable.
Playwright Configuration (playwright.config.ts)
import { defineConfig } from ‘@playwright/test’;
export default defineConfig({
use:{
headless:true,
viewport:{
width:1280,
height:720
},
screenshot:’only-on-failure’,
video:’retain-on-failure’
}
});
Explanation
- headless:true runs tests without opening the browser UI.
- viewport defines the browser window size.
- screenshot:’only-on-failure’ captures screenshots when a test fails.
- video:’retain-on-failure’ stores videos only for failed tests, helping with debugging.
Best Practices for Playwright Page Object Model
- Keep locators inside Page Objects.
- Avoid duplicate code.
- Use reusable methods.
- Follow naming conventions.
- Use TypeScript interfaces.
- Use fixtures.
- Keep tests short.
- Store test data separately.
- Use explicit assertions.
- Follow the Single Responsibility Principle.
- Create one class per page.
- Use stable locators like data-testid.
- Group related actions into business methods.
- Keep configuration separate.
- Generate HTML reports after execution.
- Use Git for version control.
- Integrate with CI/CD pipelines.
- Review and refactor page classes regularly.
Common Mistakes
Avoid these common issues:
- Writing locators inside test files.
- Hardcoding usernames and passwords.
- Creating overly large page classes.
- Ignoring reusable methods.
- Using unstable XPath locators.
- Copy-pasting the same code.
- Not organizing the project structure.
- Mixing assertions with page object methods.
Real-Time Enterprise Framework Example
Imagine an e-commerce application.
Pages
HomePage
LoginPage
ProductPage
CartPage
CheckoutPage
OrderPage
Workflow:
Home
↓
Login
↓
Products
↓
Cart
↓
Checkout
↓
Payment
↓
Order Success
Each page has:
- Locators
- Business methods
- Assertions (preferably kept in tests or dedicated helper classes)
- Reusable actions
This modular approach makes the Enterprise Playwright framework easier to scale as the application grows.
Selenium vs Playwright Page Object Model
| Feature | Selenium | Playwright |
| Auto Wait | No | Yes |
| Speed | Medium | Fast |
| Parallel Testing | Limited | Built-in |
| Multiple Browsers | Yes | Yes |
| Mobile Testing | Limited | Built-in |
| Network Mocking | External tools | Built-in |
| Setup | More configuration | Simple |
| Modern APIs | Moderate | Excellent |
Playwright TypeScript Page Object Model Interview Questions
1. What is Page Object Model?
A design pattern that separates UI locators and actions from test scripts.
2. Why use POM?
To improve code reuse, readability, and maintenance.
3. Why TypeScript?
Type safety, better IDE support, and fewer runtime errors.
4. What is a Locator?
An object used to identify and interact with page elements.
5. Why avoid duplicate locators?
Centralizing locators makes updates easier when the UI changes.
6. What is a Fixture?
Reusable setup code shared across tests.
7. What is auto waiting?
Playwright automatically waits for elements to become actionable before interacting with them.
8. What is getByRole()?
A locator based on accessibility roles, making tests more stable and user-focused.
9. Why separate page classes?
To follow the Single Responsibility Principle and improve maintainability.
10. What is playwright.config.ts?
The central configuration file for browser, reporter, retries, timeouts, and other settings.
11. Can one page object call another?
Yes, when implementing complete business workflows, though dependencies should remain clear.
12. What are fixtures used for?
Browser setup, authentication, shared test data, and environment preparation.
13. How do you make a framework scalable?
Use modular page objects, reusable utilities, fixtures, configuration management, and CI/CD integration.
14. Why avoid hardcoded test data?
It reduces flexibility and makes maintenance harder.
15. How do you organize test data?
Store it in JSON, CSV, or dedicated data providers.
16. What is a business method?
A method that performs a complete user action, such as login() or checkout().
17. What is the advantage of Playwright over Selenium?
Built-in auto waiting, faster execution, and modern automation features.
18. What is headless mode?
Running browser tests without displaying the browser window.
19. How do you debug failed tests?
Use traces, screenshots, videos, logs, and Playwright Inspector.
20. What are the characteristics of a good Page Object?
Reusable, readable, maintainable, and focused on a single page.
FAQs
1. What is the Playwright TypeScript Page Object Model?
A design pattern that organizes locators and page actions into reusable classes.
2. Is Playwright better than Selenium?
For many modern web applications, Playwright offers faster execution and built-in features such as auto waiting and tracing.
3. Is TypeScript mandatory?
No, but it is highly recommended for larger automation projects.
4. Can beginners learn Playwright?
Yes. Its API is simple and well documented.
5. What is the main benefit of POM?
Better maintainability and code reuse.
6. Should every page have its own class?
Yes, in most enterprise frameworks.
7. Can I use POM with API tests?
Yes. You can combine UI page objects with API helper classes.
8. What is the best locator strategy?
Use getByRole(), getByLabel(), or data-testid whenever possible.
9. Is Playwright free?
Yes. Playwright is open source.
10. Is Playwright suitable for enterprise automation?
Yes. It supports parallel execution, CI/CD, multiple browsers, reporting, and advanced debugging.
