POMs with AI
Lift repeated locators into a Page Object Model with the agent doing the typing — and decide which methods earn their keep.
You drove a flow and generated tests in lesson 2. The next two lessons take it one step further: instead of asking the agent to write a test, you ask it to restructure what's already there. Page Object Models and fixtures are the two refactorings I reach for most — both mechanical, both perfect agent fodder.
What is a Page Object Model?
When the same locators show up across three or more specs, a Page Object Model pulls them into one place — a class that owns the locators for a single page and exposes the meaningful actions on it.
A POM that pulls its weight is a handful of locators with action methods on top:
import type { Page, Locator } from "@playwright/test";
export class ProductPage {
readonly page: Page; readonly addToCartButton: Locator;
readonly title: Locator;
readonly price: Locator;
constructor(page: Page) {
this.page = page;
this.addToCartButton = page.getByLabel("Add item to cart");
this.title = page.getByRole("heading", { level: 1 });
this.price = page.getByTestId("price");
} async goto(handle: string) {
await this.page.goto(`/product/${handle}`);
}
async addToCart() {
await this.addToCartButton.click();
}
}import { test, expect } from "@playwright/test";import { ProductPage } from "./poms/product-page"; test("adds a snowboard to the cart", async ({ page }) => { const product = new ProductPage(page); await product.goto("snowboard"); await expect(product.title).toContainText(/snowboard/i); await product.addToCart();});Once the class exists, every spec that touches the product page costs three lines, not thirty.
Let the agent do the extraction
Drafting the class is mechanical pattern-matching — exactly the work an agent is good at. Reading three specs, finding the locators they share, and lifting them into a class is typing-heavy work with a reviewable diff.
What to push back on: locator getters that just rename page.getByLabel('X') to productPage.x — those don't earn their keep. Action methods (addToCart() not clickAddToCartButton()) do.
Hand the POM extraction to the agent
Extract a ProductPage POM
Identify two specs in your repo that both touch a product detail page (the snowboard test from lesson 2 and the cart spec are good candidates). Try drafting the prompt yourself first, then reveal the one below to compare. Read the proposed class — are the methods actions or thin getters? Apply when it survives review and re-run both tests.
Show an example prompt
Can you take the existing spec.ts files and refactor them to use page object
models (POMs). Extract proper pages and place them in tests/poms/ with
action methods (not locator getters). Use the Playwright CLI to evaluate for correctness!
Read the Playwright docs for an example: https://playwright.dev/docs/pom.