This commit is contained in:
Debbie O'Brien 2022-09-09 20:33:14 +02:00 коммит произвёл GitHub
Родитель b4259d7527
Коммит 47b9595b95
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
1 изменённых файлов: 175 добавлений и 45 удалений

Просмотреть файл

@ -2,54 +2,198 @@
id: pom
title: "Page Object Models"
---
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.
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.
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.
<!-- TOC -->
## Playwright Test vs. Library
* langs: js
:::caution
This guide is for [Playwright Library](./library.md), if you are using Playwright Test (`@playwright/test`) see [here](./test-pom.md).
:::
## Introduction
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.
Page objects **simplify authoring**. They create a higher-level API which suits your application.
Page objects **simplify maintenance**. They capture element selectors in one place and create reusable code to avoid
repetition.
Page objects **simplify authoring** by creating a higher-level API which suits your application and **simplify maintenance** by capturing element selectors in one place and create reusable code to avoid repetition.
## Implementation
* langs: js
Page object models wrap over a Playwright [Page].
We will create a `PlaywrightDevPage` helper class to encapsulate common operations on the `playwright.dev` page. Internally, it will use the `page` object.
```js
// models/Search.js
class SearchPage {
```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: 'Writing Tests' }).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();
}
}
```
```js tab=js-library
// models/PlaywrightDevPage.js
class PlaywrightDevPage {
/**
* @param {import('playwright').Page} page
*/
constructor(page) {
this.page = page;
this.searchTermInput = page.locator('[aria-label="Enter your search term"]');
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 navigate() {
await this.page.goto('https://bing.com');
async getStarted() {
await this.getStartedLink.first().click();
await expect(this.gettingStartedHeader).toBeVisible();
}
async search(text) {
await this.searchTermInput.fill(text);
await this.searchTermInput.press('Enter');
async pageObjectModel() {
await this.getStarted();
await this.pomLink.click();
}
}
module.exports = { SearchPage };
module.exports = { PlaywrightDevPage };
```
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');
});
```
```js tab=js-library
// example.spec.js
const { PlaywrightDevPage } = require('./playwright-dev-page');
// In the test
const page = await browser.newPage();
await playwrightDev.goto();
await playwrightDev.getStarted();
await expect(playwrightDev.tocList).toHaveText([
'Installation',
'First test',
'Configuration file',
'Writing assertions',
'Using test fixtures',
'Using test hooks',
'VS Code extension',
'Command line',
'Configure NPM scripts',
'Release notes'
]);
```
## Implementation
* langs: java, csharp, python
Page object models wrap over a Playwright [Page].
```java
// models/SearchPage.java
package models;
@ -138,17 +282,6 @@ public class SearchPage
Page objects can then be used inside a test.
```js
// search.spec.js
const { SearchPage } = require('./models/Search');
// In the test
const page = await browser.newPage();
const searchPage = new SearchPage(page);
await searchPage.navigate();
await searchPage.search('search query');
```
```java
import models.SearchPage;
import com.microsoft.playwright.*;
@ -191,6 +324,3 @@ var page = new SearchPage(await browser.NewPageAsync());
await page.GotoAsync();
await page.SearchAsync("search query");
```
### API reference
- [Page]