--- id: test-pom title: "Page Object Model" --- Page Object Model is a common pattern that introduces abstractions over web app pages to simplify interactions with them in multiple tests. It is best explained by an example. We will create a `PlaywrightDevPage` helper class to encapsulate common operations on the `playwright.dev` page. Internally, it will use the `page` object. ```js tab=js-js // playwright-dev-page.js const { expect } = require('@playwright/test'); exports.PlaywrightDevPage = class PlaywrightDevPage { /** * @param {import('@playwright/test').Page} page */ constructor(page) { this.page = page; this.getStartedLink = page.locator('a', { hasText: 'Get started' }); this.gettingStartedHeader = page.locator('h1', { hasText: 'Installation' }); this.pomLink = page.locator('li', { hasText: 'Playwright Test' }).locator('a', { hasText: 'Page Object Model' }); this.tocList = page.locator('article div.markdown ul > li > a'); } async goto() { await this.page.goto('https://playwright.dev'); } async getStarted() { await this.getStartedLink.first().click(); await expect(this.gettingStartedHeader).toBeVisible(); } async pageObjectModel() { await this.getStarted(); await this.pomLink.click(); } } ``` ```js tab=js-ts // playwright-dev-page.ts import { expect, Locator, Page } from '@playwright/test'; export class PlaywrightDevPage { readonly page: Page; readonly getStartedLink: Locator; readonly gettingStartedHeader: Locator; readonly pomLink: Locator; readonly tocList: Locator; constructor(page: Page) { this.page = page; this.getStartedLink = page.locator('a', { hasText: 'Get started' }); this.gettingStartedHeader = page.locator('h1', { hasText: 'Installation' }); this.pomLink = page.locator('li', { hasText: 'Playwright Test' }).locator('a', { hasText: 'Page Object Model' }); this.tocList = page.locator('article div.markdown ul > li > a'); } async goto() { await this.page.goto('https://playwright.dev'); } async getStarted() { await this.getStartedLink.first().click(); await expect(this.gettingStartedHeader).toBeVisible(); } async pageObjectModel() { await this.getStarted(); await this.pomLink.click(); } } ``` Now we can use the `PlaywrightDevPage` class in our tests. ```js tab=js-js // example.spec.js const { test, expect } = require('@playwright/test'); const { PlaywrightDevPage } = require('./playwright-dev-page'); test('getting started should contain table of contents', async ({ page }) => { const playwrightDev = new PlaywrightDevPage(page); await playwrightDev.goto(); await playwrightDev.getStarted(); await expect(playwrightDev.tocList).toHaveText([ `How to install Playwright`, `What's Installed`, `How to run the example test`, `How to open the HTML test report`, `Write tests using web first assertions, page fixtures and locators`, `Run single tests, multiple tests, headed mode`, `Generate tests with Codegen`, `See a trace of your tests` ]); }); test('should show Page Object Model article', async ({ page }) => { const playwrightDev = new PlaywrightDevPage(page); await playwrightDev.goto(); await playwrightDev.pageObjectModel(); await expect(page.locator('article')).toContainText('Page Object Model is a common pattern'); }); ``` ```js tab=js-ts // example.spec.ts import { test, expect } from '@playwright/test'; import { PlaywrightDevPage } from './playwright-dev-page'; test('getting started should contain table of contents', async ({ page }) => { const playwrightDev = new PlaywrightDevPage(page); await playwrightDev.goto(); await playwrightDev.getStarted(); await expect(playwrightDev.tocList).toHaveText([ `How to install Playwright`, `What's Installed`, `How to run the example test`, `How to open the HTML test report`, `Write tests using web first assertions, page fixtures and locators`, `Run single tests, multiple tests, headed mode`, `Generate tests with Codegen`, `See a trace of your tests` ]); }); test('should show Page Object Model article', async ({ page }) => { const playwrightDev = new PlaywrightDevPage(page); await playwrightDev.goto(); await playwrightDev.pageObjectModel(); await expect(page.locator('article')).toContainText('Page Object Model is a common pattern'); }); ```