playwright/docs/src/test-pom-js.md
2021-07-27 17:22:08 +02:00

3.7 KiB

id title
test-pom 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.

// playwright-dev-page.js
exports.PlaywrightDevPage = class PlaywrightDevPage {
  /**
   * @param {import('playwright').Page} page 
   */
  constructor(page) {
    this.page = page;
  }

  async goto() {
    await this.page.goto('https://playwright.dev');
  }

  async toc() {
    const text = await this.page.innerText('article ul');
    return text.split('\n').filter(line => !!line);
  }

  async getStarted() {
    await this.page.click('text=Get started');
    await this.page.waitForSelector(`text=Core concepts`);
  }

  async coreConcepts() {
    await this.getStarted();
    await this.page.click('text=Core concepts');
    await this.page.waitForSelector(`h1:has-text("Core concepts")`);
  }
}
// playwright-dev-page.ts
import type { Page } from 'playwright';

export class PlaywrightDevPage {
  readonly page: Page;

  constructor(page: Page) {
    this.page = page;
  }

  async goto() {
    await this.page.goto('https://playwright.dev');
  }

  async toc() {
    const text = await this.page.innerText('article ul');
    return text.split('\n').filter(line => !!line);
  }

  async getStarted() {
    await this.page.click('text=Get started');
    await this.page.waitForSelector(`text=Core concepts`);
  }

  async coreConcepts() {
    await this.getStarted();
    await this.page.click('text=Core concepts');
    await this.page.waitForSelector(`h1:has-text("Core concepts")`);
  }
}

Now we can use the PlaywrightDevPage class in our tests.

// example.spec.js
const { test, expect } = require('@playwright/test');
const { PlaywrightDevPage } = require('./playwright-dev-page');

test('Get Started table of contents', async ({ page }) => {
  const playwrightDev = new PlaywrightDevPage(page);
  await playwrightDev.goto();
  await playwrightDev.getStarted();
  expect(await playwrightDev.toc()).toEqual([
    'Installation',
    'Usage',
    'First script',
    'Record scripts',
    'TypeScript support',
    'System requirements',
    'Release notes'
  ]);
});

test('Core Concepts table of contents', async ({ page }) => {
  const playwrightDev = new PlaywrightDevPage(page);
  await playwrightDev.goto();
  await playwrightDev.coreConcepts();
  expect(await playwrightDev.toc()).toEqual([
    'Browser',
    'Browser contexts',
    'Pages and frames',
    'Selectors',
    'Auto-waiting',
    'Execution contexts: Playwright and Browser',
    'Evaluation Argument'
  ]);
});
// example.spec.ts
import { test, expect } from '@playwright/test';
import { PlaywrightDevPage } from './playwright-dev-page';

test('Get Started table of contents', async ({ page }) => {
  const playwrightDev = new PlaywrightDevPage(page);
  await playwrightDev.goto();
  await playwrightDev.getStarted();
  expect(await playwrightDev.toc()).toEqual([
    'Installation',
    'Usage',
    'First script',
    'Record scripts',
    'TypeScript support',
    'System requirements',
    'Release notes'
  ]);
});

test('Core Concepts table of contents', async ({ page }) => {
  const playwrightDev = new PlaywrightDevPage(page);
  await playwrightDev.goto();
  await playwrightDev.coreConcepts();
  expect(await playwrightDev.toc()).toEqual([
    'Browser',
    'Browser contexts',
    'Pages and frames',
    'Selectors',
    'Auto-waiting',
    'Execution contexts: Playwright and Browser',
    'Evaluation Argument'
  ]);
});