PW Page Object Builder
Builds a Page Object for this framework. Every POM here extends BasePage; none of them
build locators in the base class.
Read first
src/pages/LoginPage.ts is the reference implementation. src/pages/BasePage.ts is the contract.
Match them rather than a generic Playwright POM.
Contract
extends BasePage, constructor callssuper(page, '<ClassName>')so the logger is scoped.static readonly PATHfor the route. Navigate withthis.goto(PATH), neverpage.gotowith an absolute URL, sobaseURLfromplaywright.config.tsstill applies.- Locators are
private readonlyfields assigned in the constructor. This app isdata-testdriven, so prefer[data-test="..."]. Expose behaviour, never the Locator. - All interaction goes through
this.el.*(UtilElementLocator), neverlocator.click()directly. That wrapper is what puts every action in the log. - Dynamic locators become private helper methods, e.g.
addBtn(id), not public fields. - Provide
assertLoaded()using web-first assertions.
Output shape
import { expect, Locator, Page } from '@playwright/test';
import { BasePage } from './BasePage';
export class InventoryPage extends BasePage {
static readonly PATH = '/playwright/ttacart/inventory.html';
private readonly title: Locator;
private readonly cartLink: Locator;
constructor(page: Page) {
super(page, 'InventoryPage');
this.title = page.locator('[data-test="title"]');
this.cartLink = page.locator('[data-test="shopping-cart-link"]');
}
async open(): Promise<void> {
await this.goto(InventoryPage.PATH);
await this.assertLoaded();
}
async assertLoaded(): Promise<void> {
await expect(this.title).toHaveText('Products');
}
private addBtn(id: string): Locator {
return this.page.locator(`[data-test="add-to-cart-${id}"]`);
}
async addToCart(id: string): Promise<void> {
await this.el.click(this.addBtn(id));
}
}
Then wire it up
A new POM is only half done. Add a fixture for it in src/fixtures/test-base.ts: a field on the
TestFixture type and a base.extend entry that constructs it against page. Specs must get
page objects from the fixture, never with new.
Verify
npx tsc --noEmit -p tsconfig.json