LoginSignup
5
0

Playwright で Page Object Model を使用するときのちょっとした工夫

Last updated at Posted at 2023-12-21

はじめに

本記事は、株式会社ACCESS Advent Calendar 2023 の22日目の記事です。
Playwright における Page Object Model の使用方法が公式ドキュメントにガイドとして、紹介されている。
本記事ではさらに Playwright で Page Object Model を使用するときのちょっとした工夫について紹介する。

コード

対象の HTML

対象の HTML は以下のものとする。一般的なログインフォームを想定している。

<form action="/login" method="POST" enctype="application/json">
  <div>
    <label for="username-field">username</label>
    <input type="text" id="username-field" required/>
  </div>
  <div>
    <label for="password-field">password</label>
    <input type="password" id="password-field" required/>
  </div>
  <button id="login">Login</button>
</form>

Page Object Model

上記の対象の HTML に対して、以下のような Page Object Model を作成する。

import { expect, type Locator, type Page } from '@playwright/test';

export class LoginPage {
  readonly page: Page;
  readonly usernameTextBox: Locator;
  readonly passwordTextBox: Locator;
  readonly loginButton: Locator;

  constructor(page: Page) {
    this.page = page;
    this.usernameTextBox = page.getByRole(
      "textarea",
      {
        name: "username"
      }
    );
    this.passwordTextBox = page.getByRole(
      "textarea",
      {
        name: "password"
      }
    );
    this.loginButton = page.getByRole(
      "button",
      {
        name: "Login"
      }
    );
  }

  async login(username: string, password: string) {
    await this.usernameTextBox.fill(username);
    await this.passwordTextBox.fill(password);
    await this.loginButton.click();
  }
}

ちょっとした工夫

冒頭でも参照したガイドでは Page Object を定義したクラスのインスタンスを test のコールバック関数内で生成している。

test('should be able to login', async ({ page }) => {
  const loginPage = new LoginPage(page);
  await loginPage.login('user', 'pass');
});

しかし、この方法では、テストケースを定義するたびに、インスタンスを生成するコードを各必要がある。たった一行だけれど、毎回記述するのは個人的には鬱陶しい。そこで、ちょっとした工夫として紹介するのが Fixture のなかでインスタンスを生成するものである。

import { test as base, Page } from "@playwright/test";

type TestFixtures = {
  loginPage: LoginPage;
};

const test = base.extend<TestFixtures>({
  loginPage: async ({ page }, use) => {
    const loginPage: = new LoginPage(page);
    await use(loginPage);
  },
});

test('should be able to login', async ({ loginPage }) => {
  await loginPage.login('user', 'pass');
});

Fixture を使用することで Fixture を呼び出すたびに Page Object のクラスのインスタンスの生成が実行される。
実はこの実装方法は、公式ドキュメントの Fixtures にしれっと記載されている...。

さいごに

Playwright で Page Object Model を使用する際のちょっとした工夫について紹介した。結局のところ、この記事の味噌は Fixture の使用方法についての紹介となったが、テストケースの前後の処理などにも使用できるため、ぜひ活用してみてほしい。
明日は @Momijinn さんの記事です。お楽しみに!

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0