Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

145 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

playwright-page-object

Typed, decorator-driven Page Object Model for Playwright. Reusable, lazy locator chains in plain TypeScript classes.

npm version CI TypeScript License: MIT

Documentation: https://pom.shmakov.tools/


MCP server for AI coding agents

The package includes a local, read-only MCP server that lets AI coding agents inspect your existing page objects and JSX or TSX test IDs before editing tests. Agents can follow typed locator chains, reuse selectors already in the repository, and check selector coverage without launching a browser or executing application code.

It works with local stdio MCP clients including Claude Code, Cursor, VS Code, and Codex CLI. The server exposes five tools for discovering page objects, reading selector trees, finding test IDs, and auditing coverage.

Explore the MCP server docs → · Connect your MCP client →

Before / after

// Before — selectors duplicated, structure invisible
await page.getByTestId("CheckoutPage").getByTestId("PromoCodeInput").fill("SAVE20");
await page.getByTestId("CheckoutPage").getByRole("button", { name: "Apply" }).click();
// After — typed, composable, reusable
await checkoutPage.applyPromoCode("SAVE20");

What it is

A locator-composition layer, not a framework. Decorators scope a class to a Playwright locator; child decorators resolve relative to that scope. The accessor type determines output: raw Locator, a custom control, or a built-in PageObject.

  • No inheritance required for basic use
  • Lazy locator chains rebuild only when accessed
  • Three output styles coexist in the same suite
  • TypeScript-first, ECMAScript decorators (no experimentalDecorators needed)

Install

npm install -D playwright-page-object

Requirements:

  • Node >=20
  • @playwright/test >=1.35.0
  • TypeScript >=5.0 (with target: "ES2015" or higher)

Quick start

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;

  async applyPromoCode(code: string) {
    await this.PromoCodeInput.fill(code);
    await this.ApplyButton.click();
  }
}
import { test } from "@playwright/test";

test("apply promo code", async ({ page }) => {
  const checkout = new CheckoutPage(page);
  await checkout.applyPromoCode("SAVE20");
});

See the Quick Start guide for fixtures, page-only hosts, and the next steps.

Output styles

Three styles, picked per accessor. Mix freely in the same class.

Raw Locator

Minimal abstraction. Typed accessor, no helpers.

@Selector("PromoCodeInput")
accessor PromoCodeInput!: Locator;

Plain Classes guide →

Custom controls

Pass any class whose constructor accepts a Locator. Reuse your existing control library.

@Selector("PromoCodeInput", InputControl)
accessor PromoCode!: InputControl;

Custom Controls guide →

Built-in POM

PageObject / ListPageObject for wait helpers, soft assertions, and filter chains.

class CheckoutPage extends RootPageObject {
  @Selector("PromoCodeInput")
  accessor PromoCode = new PageObject();

  async applyPromo(code: string) {
    await this.PromoCode.waitVisible();
    await this.PromoCode.$.fill(code);
  }
}

Built-In POM guide →

Context resolution

Child decorators resolve in this order: a @RootSelector-managed locator, then a locator property on the host, then page.locator("body") if page is present. The first match wins.

Context Resolution reference →

Documentation

The full documentation site covers every guide, the API reference, and the v1 → v2 migration:

https://pom.shmakov.tools/

  • Getting Started — install, quick start, choosing a style
  • Guides — plain classes, fragments, custom controls, built-in POM, lists, fixtures, incremental adoption
  • Reference — context resolution, migration v1 → v2, troubleshooting
  • API — decorators, PageObject, RootPageObject, ListPageObject, createFixtures

More AI tooling

This package also ships an Agent Skills-compatible skill so AI assistants load library-specific guidance on demand:

npx ctx7 skills install /sergeyshmakov/playwright-page-object playwright-page-object

It is also indexed in Context7 and documented in a Cubic wiki. See AI Tooling in the docs.

Migrating from v1

See the migration guide. Most changes are mechanical renames.

Contributing

See CONTRIBUTING.md.

License

MIT License

About

Typed, decorator-driven Page Object Model for Playwright. Reusable, lazy locator chains in plain TypeScript classes.

Topics

Resources

Code of conduct

Contributing

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages