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().
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.
Type parameters
Section titled “Type parameters”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
Section titled “Options”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"); }}Constructor
Section titled “Constructor”new PageObject()
Section titled “new PageObject()”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
-
pagePageThe page the page object works on.
-
baseUrlstring | RegExpThe origin, such as
https://shop.example, or a RegExp tested against the URL’s origin (declarebaseUrlType: RegExpinOptions). See baseUrl and urlPath. -
urlPathstring | RegExpThe page’s path:
""or a string that starts with one/, such as/login, or a RegExp tested against the rest of the URL (declareurlPathType: RegExpinOptions). -
optionsPageObjectOptions (optional)-
labelstring (optional)Prefix of the page object’s step titles and error messages. Defaults to the class name.
-
navOptionsNavigationOptions (optional)Defaults for every navigation method of
navigation(waitUntil,timeout); a call’s own options win. -
sessionStorageObject (optional)-
schemaSessionStorageSchema (optional)The codecs of the session storage keys that hold structured values; its type is
Options["storage"].
-
-
locatorsLocatorRegistryOptions (optional)-
strictChainsboolean (optional)truemakes the registry verification require every ancestor of every path to be registered. Defaults tofalse.
-
-
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".Methods to implement
Section titled “Methods to implement”defineLocators()
Section titled “defineLocators()”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".pageActionsToPerformAfterNavigation()
Section titled “pageActionsToPerformAfterNavigation()”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.
[]andnullboth mean no actions; the default returns[].
Properties
Section titled “Properties”Registers a locator for a path: this.add(path) followed by one of the ten locator methods. Used inside
defineLocators(). See LocatorRegistry.add().
Type
- AddAccessor<Paths>
baseUrl
Section titled “baseUrl”The baseUrl the page object was constructed with.
Type
- string | RegExp, as declared in
Options
fullUrl
Section titled “fullUrl”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
- string | UrlMatcher
getLocator
Section titled “getLocator”Resolves the locator registered for a path, alone. See
LocatorRegistry.getLocator().
Type
- GetLocatorAccessor<Paths>
getLocatorSchema
Section titled “getLocatorSchema”Starts a query of a path, to change its chain for one use. See
LocatorQueryBuilder.
Type
- GetLocatorSchemaAccessor<Paths>
getNestedLocator
Section titled “getNestedLocator”Resolves a path to the chain of every registered segment. See
LocatorRegistry.getNestedLocator().
Type
- GetNestedLocatorAccessor<Paths>
The label from the constructor options, or the class name.
Type
- string
locatorRegistry
Section titled “locatorRegistry”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
- LocatorRegistry<Paths>
navigation
Section titled “navigation”The navigation helper: goto(), expectThisPage() and expectAnotherPage(). See
NavigationFor.
Type
- NavigationFor<BaseUrl, FullUrl>
The Playwright page the page object was constructed with.
Type
sessionStorage
Section titled “sessionStorage”The session storage helper for the page object’s origin, typed by the schema. See
SessionStorage and
through a page object.
Type
- SessionStorage<Schema>
urlPath
Section titled “urlPath”The urlPath the page object was constructed with.
Type
- string | RegExp, as declared in
Options