Skip to content

PageObject

PageObject is the abstract base class of a page object. It binds a Playwright Page to a locator registry, a navigation helper built from the page object’s URL, and a session storage helper for its origin. A subclass names its paths, calls the constructor with its URL, and registers its locators in defineLocators().

login.page.ts
import type { Page } from "@playwright/test";
import { PageObject } from "pomwright";
type Paths = "main" | "main.button@login";
export class LoginPage extends PageObject<Paths> {
constructor(page: Page) {
super(page, "https://shop.example", "/login");
}
protected defineLocators(): void {
this.add("main").locator("main");
this.add("main.button@login").getByRole("button", { name: "Log in" });
}
}

Guide: your first page object, page objects.


Paths extends string

The union of the page object’s locator paths. TypeScript checks every path passed to the locator methods against it, and against the rules of a path, which POMWright checks again at runtime. See what a path is.

Options extends PageObjectTypeOptions (optional)

Types only: whether baseUrl and urlPath are RegExps (both default to string), and the type of the session storage schema. See pages whose URL varies and session storage through a page object.

import type { Page } from "@playwright/test";
import { json, PageObject } from "pomwright";
const orderStorage = { cart: json<{ items: string[] }>() };
export class OrderPage extends PageObject<"main", { urlPathType: RegExp; storage: typeof orderStorage }> {
constructor(page: Page) {
super(page, "https://shop.example", /^\/orders\/\d+$/, { sessionStorage: { schema: orderStorage } });
}
protected defineLocators(): void {
this.add("main").locator("main");
}
}

Called from the subclass constructor as super(...); the constructor is protected. It checks the URL parts, creates the registry and the helpers, and schedules defineLocators().

Usage

import type { Page } from "@playwright/test";
import { PageObject } from "pomwright";
export class AccountPage extends PageObject<"main"> {
constructor(page: Page) {
super(page, "https://shop.example", "/account", {
label: "Account",
navOptions: { waitUntil: "domcontentloaded" },
});
}
protected defineLocators(): void {
this.add("main").locator("main");
}
}

Arguments

  • page Page

    The page the page object works on.

  • baseUrl string | RegExp

    The origin, such as https://shop.example, or a RegExp tested against the URL’s origin (declare baseUrlType: RegExp in Options). See baseUrl and urlPath.

  • urlPath string | RegExp

    The page’s path: "" or a string that starts with one /, such as /login, or a RegExp tested against the rest of the URL (declare urlPathType: RegExp in Options).

  • options PageObjectOptions (optional)

    • label string (optional)

      Prefix of the page object’s step titles and error messages. Defaults to the class name.

    • navOptions NavigationOptions (optional)

      Defaults for every navigation method of navigation (waitUntil, timeout); a call’s own options win.

    • sessionStorage Object (optional)

      • schema SessionStorageSchema (optional)

        The codecs of the session storage keys that hold structured values; its type is Options["storage"].

    • locators LocatorRegistryOptions (optional)

      • strictChains boolean (optional)

        true makes the registry verification require every ancestor of every path to be registered. Defaults to false.

Throws

When a URL part is not what it must be:

LoginPage: baseUrl must be an origin such as "https://example.com" or "http://localhost:9000" (scheme, host, optional port, no path, query or hash); received "localhost:9000".
LoginPage: baseUrl must be a string or a RegExp; received undefined.
LoginPage: urlPath must be "" or start with exactly one "/"; received "login".

protected abstract

Registers the page object’s locators with this.add(path). Implement it in every page object. It runs once, right after the constructor, so it can use the subclass’s constructor arguments and fields, and the registry is verified after it. See when defineLocators() runs.

Usage

import type { Page } from "@playwright/test";
import { PageObject } from "pomwright";
const loginLabel = { en: "Log in", nb: "Logg inn" } as const;
export class LoginPage extends PageObject<"main" | "main.button@login"> {
constructor(page: Page, private readonly locale: "en" | "nb") {
super(page, "https://shop.example", "/login");
}
protected defineLocators(): void {
this.add("main").locator("main");
this.add("main.button@login").getByRole("button", { name: loginLabel[this.locale] });
}
}

Returns

  • void

Throws

An error inside defineLocators() or from the verification after it, labelled with the page object and kept for every later locator call; see how a mistake is reported.

LoginPage: defineLocators() failed: A locator schema with the path "main" already exists. …
LoginPage: Locator registry verification failed for 1 of 5 paths:
"main.form@login": No locator schema registered for path "main.form@login.heading".

protected, optional

Returns the actions to run after navigation.goto() without a target and after navigation.expectThisPage(), such as waiting for a spinner to go away. See actions after navigation.

Usage

import { expect, type Page } from "@playwright/test";
import { PageObject } from "pomwright";
export class DashboardPage extends PageObject<"main" | "main.spinner"> {
constructor(page: Page) {
super(page, "https://shop.example", "/dashboard");
}
protected defineLocators(): void {
this.add("main").locator("main");
this.add("main.spinner").getByRole("progressbar");
}
protected pageActionsToPerformAfterNavigation() {
return [
async () => {
await expect(this.getNestedLocator("main.spinner")).toBeHidden();
},
];
}
}

Returns

  • Array<() => Promise<void>> | null

    Run in order. [] and null both mean no actions; the default returns [].


Registers a locator for a path: this.add(path) followed by one of the ten locator methods. Used inside defineLocators(). See LocatorRegistry.add().

Type

The baseUrl the page object was constructed with.

Type

  • string | RegExp, as declared in Options

The page object’s URL: new URL(urlPath, baseUrl).href for two strings, a UrlMatcher when either part is a RegExp. See fullUrl.

Usage

await expect(page).toHaveURL(loginPage.fullUrl);

Type

Resolves the locator registered for a path, alone. See LocatorRegistry.getLocator().

Type

Starts a query of a path, to change its chain for one use. See LocatorQueryBuilder.

Type

Resolves a path to the chain of every registered segment. See LocatorRegistry.getNestedLocator().

Type

The label from the constructor options, or the class name.

Type

  • string

protected

The page object’s registry, for code that takes a registry, such as a locator module: defineLocators(this.locatorRegistry). Every method of it except createReusable runs defineLocators() first if it has not run yet.

Type

The navigation helper: goto(), expectThisPage() and expectAnotherPage(). See NavigationFor.

Type

The Playwright page the page object was constructed with.

Type

The session storage helper for the page object’s origin, typed by the schema. See SessionStorage and through a page object.

Type

The urlPath the page object was constructed with.

Type

  • string | RegExp, as declared in Options