PageSourceSearch

https://playwright.dev/assets/js/04a4d366.dab2a3f2.js

js playwright.dev collected 2026-09-24 06:54:47 UTC 6,756 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkplaywright_dev=self.webpackChunkplaywright_dev||[]).push([["2712"],{52365(e,t,a){a.r(t),a.d(t,{metadata:()=>n,default:()=>h,frontMatter:()=>l,contentTitle:()=>c,toc:()=>p,assets:()=>g});var n=JSON.parse('{"id":"pom","title":"Page object models","description":"Introduction","source":"@site/versioned_docs/version-stable/pom.mdx","sourceDirName":".","slug":"/pom","permalink":"/docs/pom","draft":false,"unlisted":false,"tags":[],"version":"stable","frontMatter":{"id":"pom","title":"Page object models"},"sidebar":"docs","previous":{"title":"Pages","permalink":"/docs/pages"},"next":{"title":"Screenshots","permalink":"/docs/screenshots"}}'),s=a(74848),i=a(28453),r=a(13554),o=a(41647);a(83137);let l={id:"pom",title:"Page object models"},c,g={},p=[{value:"Introduction",id:"introduction",level:2},{value:"Implementation",id:"implementation",level:2}];function d(e){let t={code:"code",h2:"h2",p:"p",pre:"pre",strong:"strong",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsx)(t.p,{children:"Large test suites can be structured to optimize ease of authoring and maintenance. Page object models are one such approach to structure your test suite."}),"\n",(0,s.jsx)(t.p,{children:"A page object represents a part of your web application. An e-commerce web application might have a home page, a listings page and a checkout page. Each of them can be represented by page object models."}),"\n",(0,s.jsxs)(t.p,{children:["Page objects ",(0,s.jsx)(t.strong,{children:"simplify authoring"})," by creating a higher-level API which suits your application and ",(0,s.jsx)(t.strong,{children:"simplify maintenance"})," by capturing element selectors in one place and create reusable code to avoid repetition."]}),"\n",(0,s.jsx)(t.h2,{id:"implementation",children:"Implementation"}),"\n",(0,s.jsxs)(t.p,{children:["We will create a ",(0,s.jsx)(t.code,{children:"PlaywrightDevPage"})," helper class to encapsulate common operations on the ",(0,s.jsx)(t.code,{children:"playwright.dev"})," page. Internally, it will use the ",(0,s.jsx)(t.code,{children:"page"})," object."]}),"\n",(0,s.jsxs)(r.A,{groupId:"js-flavor",defaultValue:"test",values:[{label:"Test",value:"test"},{label:"Library",value:"library"}],children:[(0,s.jsx)(o.A,{value:"test",children:(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-js",metastring:'title="playwright-dev-page.ts"',children:"import { expect, type Locator, type Page } from '@playwright/test';\n\nexport class PlaywrightDevPage {\n  readonly page: Page;\n  readonly getStartedLink: Locator;\n  readonly gettingStartedHeader: Locator;\n  readonly pomLink: Locator;\n  readonly tocList: Locator;\n\n  constructor(page: Page) {\n    this.page = page;\n    this.getStartedLink = page.locator('a', { hasText: 'Get started' });\n    this.gettingStartedHeader = page.locator('h1', { hasText: 'Installation' });\n    this.pomLink = page.locator('li', {\n      hasText: 'Guides',\n    }).locator('a', {\n      hasText: 'Page Object Model',\n    });\n    this.tocList = page.locator('article div.markdown ul > li > a');\n  }\n\n  async goto() {\n    await this.page.goto('https://playwright.dev');\n  }
1\n\n  async getStarted() {\n    await this.getStartedLink.first().click();\n    await expect(this.gettingStartedHeader).toBeVisible();\n  }\n\n  async pageObjectModel() {\n    await this.getStarted();\n    await this.pomLink.click();\n  }\n}\n"})})}),(0,s.jsx)(o.A,{value:"library",children:(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-js",metastring:'title="models/PlaywrightDevPage.js"',children:"class PlaywrightDevPage {\n  /**\n   * @param {import('playwright').Page} page\n   */\n  constructor(page) {\n    this.page = page;\n    this.getStartedLink = page.locator('a', { hasText: 'Get started' });\n    this.gettingStartedHeader = page.locator('h1', { hasText: 'Installation' });\n    this.pomLink = page.locator('li', {\n      hasText: 'Playwright Test',\n    }).locator('a', {\n      hasText: 'Page Object Model',\n    });\n    this.tocList = page.locator('article div.markdown ul > li > a');\n  }\n  async getStarted() {\n    await this.getStartedLink.first().click();\n    await expect(this.gettingStartedHeader).toBeVisible();\n  }
1\n\n  async pageObjectModel() {\n    await this.getStarted();\n    await this.pomLink.click();\n  }\n}\nmodule.exports = { PlaywrightDevPage };\n"})})})]}),"\n",(0,s.jsxs)(t.p,{children:["Now we can use the ",(0,s.jsx)(t.code,{children:"PlaywrightDevPage"})," class in our tests."]}),"\n",(0,s.jsxs)(r.A,{groupId:"js-flavor",defaultValue:"test",values:[{label:"Test",value:"test"},{label:"Library",value:"library"}],children:[(0,s.jsx)(o.A,{value:"test",children:(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-js",metastring:'title="example.spec.ts"',children:"import { test, expect } from '@playwright/test';\nimport { PlaywrightDevPage } from './playwright-dev-page';\n\ntest('getting started should contain table of contents', async ({ page }) => {\n  const playwrightDev = new PlaywrightDevPage(page);\n  await playwrightDev.goto();\n  await playwrightDev.getStarted();\n  await expect(playwrightDev.tocList).toHaveText([\n    `How to install Playwright`,\n    `What's installed`,\n    `How to run the example test`,\n    `How to open the HTML test report`,\n    `Write tests using web-first assertions, fixtures and locators`,\n    `Run single or multiple tests; headed mode`,\n    `Generate tests with Codegen`,\n    `View a trace of your tests`,\n  ]);\n});\n\ntest('should show Page Object Model article', async ({ page }) => {\n  const playwrightDev = new PlaywrightDevPage(page);\n  await playwrightDev.goto();\n  await playwrightDev.pageObjectModel();\n  await expect(page.locator('article')).toContainText('Page Object Model is a common pattern');\n});\n"})})}),(0,s.jsx)(o.A,{value:"library",children:(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-js",metastring:'title="example.spec.js"',children:"const { PlaywrightDevPage } = require('./playwright-dev-page');\n\n// In the test\nconst page = await browser.newPage();\nawait playwrightDev.goto();\nawait playwrightDev.getStarted();\nawait expect(playwrightDev.tocList).toHaveText([\n  `How to install Playwright`,\n  `What's installed`,\n  `How to run the example test`,\n  `How to open the HTML test report`,\n  `Write tests using web-first assertions, fixtures and locators`,\n  `Run single or multiple tests; headed mode`,\n  `Generate tests with Codegen`,\n  `View a trace of your tests`,\n]);\n"})})})]})]})}function h(e={}){let{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.