Introduction
Relevant source files
The following files were used as context for generating this wiki page:
playwright-page-object is a TypeScript-first framework designed to simplify Playwright end-to-end testing through a decorator-driven Page Object Model (POM). It replaces manual, often repetitive page.locator() chains with a typed, composable control graph. By using ECMAScript decorators and accessors, the library allows developers to bind class instances to top-level locators and resolve child elements relative to that context lazily.
The framework is designed for incremental adoption, meaning it can be integrated into existing Playwright suites without requiring a full rewrite. It supports plain TypeScript classes, external control libraries, and provides optional built-in base classes (RootPageObject, PageObject, and ListPageObject) for advanced functionality like built-in waits, assertions, and list management.
Sources: README.md:1-26, package.json:4-6, skills/playwright-page-object/SKILL.md:16-30
Core Concepts and Architecture
The library operates as a decorator-driven locator composition layer. It organizes UI elements into a hierarchical graph where selectors stay relative to their parent component.
The Control Graph
Page objects compose into a typed graph. For example, a checkout page might contain inputs, buttons, and a list of items, each managed as a specific control.
The diagram shows how different types of accessors (Locators, External Controls, or built-in PageObjects) resolve from a established root context.
Sources: example/README.md:41-50, README.md:46-56
Mental Model
- Root Decorators: Establish the initial locator context (e.g.,
@RootSelector("id")). - Child Decorators: Resolve selectors relative to the current root (e.g.,
@Selector("input")). - Accessor Shapes: The return type of the decorated accessor (e.g.,
accessor MyBtn!: Locator) determines whether you receive a raw Playwright Locator or a wrapped control.
Sources: README.md:92-120, skills/playwright-page-object/SKILL.md:18-35
Primary Components
The system provides three main built-in classes to handle different parts of the UI hierarchy.
Built-in Base Classes
| Class | Purpose | Key Features |
|---|---|---|
RootPageObject | Base for top-level pages. | Receives Page as the first constructor argument; establishes root context. |
PageObject | Base for nested controls/components. | Provides $ (raw locator), .expect(), and wait helpers. |
ListPageObject | Base for repeated collections. | Handles async iteration, filtering, and item count management. |
Sources: README.md:164-210, src/page-objects/PageObject.ts:44-55
Implementation of PageObject
The PageObject class serves as the foundation for nested components. It encapsulates the Playwright Locator and provides a suite of asynchronous wait methods.
// Example of wait methods in PageObject.ts
async waitVisible() {
await this.expect().toBeVisible();
}
async waitCount(count: number) {
await this.expect().toHaveCount(count);
}
Sources: src/page-objects/PageObject.ts:133-156
Integration and Fixtures
playwright-page-object simplifies test setup through automated fixture creation, removing the need for manual instantiation in every test.
createFixtures
The createFixtures() utility maps page object classes to Playwright fixtures. It works with any class where the first constructor argument is a Playwright Page.
The sequence shows how fixtures are instantiated and provided to the test environment automatically.
Sources: src/tests/fixtures.spec.ts:40-75, example/README.md:65-75
Decorator Reference
The library provides a variety of decorators that map directly to Playwright's Locator API but handle the relative context automatically.
Selector Mapping Examples
| Decorator | Playwright Equivalent | Context |
|---|---|---|
@RootSelector(id) | page.getByTestId(id) | Root |
@Selector(id) | parent.getByTestId(id) | Child |
@SelectorByRole(role, opts) | parent.getByRole(role, opts) | Child |
@ListSelector(id) | parent.getByTestId(new RegExp(id)) | Child (Collection) |
Sources: README.md:235-260, src/tests/decorators/rootSelectors.spec.ts:86-105
Conclusion
playwright-page-object provides a structured approach to Playwright testing by leveraging modern TypeScript features. By decoupling selector logic from test scripts and organizing them into a typed control graph, it improves maintainability and reusability. Whether used for simple locator management or as a full POM framework with built-in assertions and waits, it offers a flexible path for scaling test suites.
Sources: README.md:9-26, skills/playwright-page-object/SKILL.md:124-135