Fragments
A fragment is a class whose first constructor argument is Locator (not Page). It has no root decorator. Child decorators inside it chain from that locator, which is passed in by the parent.
Minimal example
Section titled “Minimal example”import type { Locator } from "@playwright/test";import { Selector } from "playwright-page-object";
class PromoSection { constructor(readonly locator: Locator) {}
@Selector("CodeInput") accessor CodeInput!: Locator;
@Selector("ApplyButton") accessor ApplyButton!: Locator;}Wiring it into a parent
Section titled “Wiring it into a parent”Pass the fragment class as the second argument to @Selector(...). The decorator constructs the fragment with the resolved locator:
@RootSelector("CheckoutPage")class CheckoutPage { constructor(readonly page: Page) {}
@Selector("PromoSection", PromoSection) accessor promo!: PromoSection;}
// Usageawait checkoutPage.promo.CodeInput.fill("SAVE20");await checkoutPage.promo.ApplyButton.click();The chain resolves as:
page.locator("body") .getByTestId("CheckoutPage") .getByTestId("PromoSection") .getByTestId("CodeInput")Context inheritance
Section titled “Context inheritance”Fragments work because the context resolution priority looks at the host’s locator property before falling back to page. The parent’s @Selector(..., FragmentClass) constructs new FragmentClass(resolvedLocator) and the resolved locator becomes the fragment’s scope.
Sharing fragments across pages
Section titled “Sharing fragments across pages”A fragment is just a class — instantiate it as a property in any page object that has the section:
@RootSelector("CheckoutPage")class CheckoutPage { constructor(readonly page: Page) {}
@Selector("PromoSection", PromoSection) accessor promo!: PromoSection;}
@RootSelector("CartPage")class CartPage { constructor(readonly page: Page) {}
@Selector("PromoSection", PromoSection) accessor promo!: PromoSection;}Both pages reuse PromoSection without inheritance or shared state.
When to pick this style
Section titled “When to pick this style”- A UI section appears on multiple pages.
- The section has its own child structure worth modeling.
- You want reusable typed accessors without forcing inheritance.
See also
Section titled “See also”- Custom Controls — fragments and custom controls share the same constructor shape.
- Context Resolution — the resolution rules that make fragments work.