Getting Started & Installation
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 enhance Playwright E2E testing by replacing raw page.locator() chains with a typed, composable, and decorator-driven control graph. It allows developers to bind class instances to top-level locators (roots) and resolve child locators relative to those roots using ECMAScript decorators and accessors.
The system is designed for incremental adoption, meaning it can be integrated into existing Playwright projects without requiring a full rewrite. It supports plain TypeScript classes, external control classes, or its own built-in base classes (RootPageObject, PageObject, and ListPageObject).
Sources: README.md:1-15, package.json:4-6, skills/playwright-page-object/SKILL.md:15-25
Installation Requirements
To use playwright-page-object, your environment must meet the following technical specifications:
| Requirement | Specification |
|---|---|
| Node.js | >=20.0.0 |
| TypeScript | >=5.0.0 (Required for accessor keyword support) |
| Playwright | >=1.35.0 |
| TSConfig Target | "ES2015" or higher |
Sources: package.json:101-112, README.md:33-38
Package Installation
Install the library as a development dependency using your preferred package manager:
npm install -D playwright-page-object
# OR
yarn add -D playwright-page-object
# OR
pnpm add -D playwright-page-object
Sources: README.md:27-31
Core Architecture & Mental Model
The framework operates on a "Control Graph" where page objects compose into a typed hierarchy. This structure ensures that selectors stay relative to their parent components, improving reusability and maintainability.
The Composition Flow
The following diagram illustrates how the framework resolves selectors from the global Page object down to specific UI elements.
The flow ensures that a child decorator like @Selector("Input") resolves as root.getByTestId("Input") rather than a global search.
Sources: README.md:65-80, example/README.md:32-40, skills/playwright-page-object/SKILL.md:27-35
Quick Start: Basic Implementation
A standard implementation requires a root decorator to establish context and child decorators for specific elements.
1. Define the Page Object
You can use a plain class that accepts page: Page in the constructor.
import type { Locator, Page } from "@playwright/test";
import { RootSelector, Selector, SelectorByRole } from "playwright-page-object";
@RootSelector("CheckoutPage")
class CheckoutPage {
constructor(readonly page: Page) {}
@Selector("PromoCodeInput")
accessor PromoCodeInput!: Locator;
@SelectorByRole("button", { name: "Apply" })
accessor ApplyButton!: Locator;
}
Sources: README.md:42-56, skills/playwright-page-object/SKILL.md:88-100
2. Use in a Test
Instantiation is straightforward, and accessors are lazy-loaded upon access.
import { test } from "@playwright/test";
test("apply promo", async ({ page }) => {
const checkout = new CheckoutPage(page);
await checkout.PromoCodeInput.fill("SAVE20");
await checkout.ApplyButton.click();
});
Sources: README.md:58-63, example/README.md:65-71
Configuration & Local Development
For developers contributing to the project or running the example suite locally, the repository uses a specific toolset for consistency.
Local Setup
# 1. Install dependencies
npm ci
# 2. Build the package
npm run build
# 3. Run development watcher (tsup)
npm run dev
Sources: CONTRIBUTING.md:26-34, package.json:11-13
Code Quality (Biome)
The project uses Biome for linting and formatting. Rules are strictly enforced via Husky pre-commit hooks to ensure zero-config contribution.
# Manually run linting/formatting
npm run lint:fix
Sources: CONTRIBUTING.md:38-46, package.json:14-15
Summary of Feature Tiers
The framework supports three distinct styles of adoption, allowing teams to choose the level of abstraction that fits their needs.
| Tier | Output Shape | Description |
|---|---|---|
| Locator-first | Locator | Direct access to Playwright Locators with decorated relative paths. |
| External Controls | Custom Class | Uses user-defined classes that accept a Locator in the constructor. |
| Built-in POM | PageObject | Provides $, .expect(), and automated wait helpers. |
Sources: README.md:95-135, skills/playwright-page-object/SKILL.md:165-175
This architectural flexibility allows the project to serve as both a minimal utility for typed selectors and a full-featured Page Object Model framework.
Sources: README.md:16-25, example/README.md:42-45