自動テストチュートリアル

Playwright、Seleniumなどの自動テストツールを学ぼう

BasePageクラスの作成

BasePageクラスの作成

共通の機能を持つ基底クラスを作成して、コードの重複を減らす方法を学びます。

BasePageとは?

すべてのPage Objectに共通する機能をまとめた基底クラスです。

BasePageの作成

// pages/BasePage.ts
import { Page, Locator } from '@playwright/test';

export abstract class BasePage {
  readonly page: Page;

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

  // 共通のナビゲーション
  async navigate(path: string) {
    await this.page.goto(path);
  }

  // ページタイトルを取得
  async getTitle(): Promise<string> {
    return await this.page.title();
  }

  // ページの読み込みを待つ
  async waitForPageLoad() {
    await this.page.waitForLoadState('networkidle');
  }

  // スクリーンショットを撮る
  async takeScreenshot(name: string) {
    await this.page.screenshot({ path: `screenshots/${name}.png` });
  }
}

BasePageを継承する

// pages/LoginPage.ts
import { Page, Locator } from '@playwright/test';
import { BasePage } from './BasePage';

export class LoginPage extends BasePage {
  readonly usernameInput: Locator;
  readonly passwordInput: Locator;
  readonly loginButton: Locator;

  constructor(page: Page) {
    super(page);  // 親クラスのコンストラクタを呼ぶ
    this.usernameInput = page.locator('#username');
    this.passwordInput = page.locator('#password');
    this.loginButton = page.locator('button[type="submit"]');
  }

  async goto() {
    await this.navigate('/login');  // BasePageのメソッドを使う
  }

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

共通コンポーネントをBasePageに追加

ヘッダーやフッターなど、全ページに表示される要素をBasePageに定義できます。

// pages/BasePage.ts
export abstract class BasePage {
  readonly page: Page;
  readonly header: Locator;
  readonly footer: Locator;
  readonly loadingSpinner: Locator;

  constructor(page: Page) {
    this.page = page;
    this.header = page.locator('header');
    this.footer = page.locator('footer');
    this.loadingSpinner = page.locator('.loading-spinner');
  }

  async waitForLoading() {
    await this.loadingSpinner.waitFor({ state: 'hidden' });
  }

  async clickHeaderLogo() {
    await this.header.locator('.logo').click();
  }
}

テストでの使用

import { test, expect } from '@playwright/test';
import { LoginPage } from '../pages';

test('ログインページのタイトルを確認', async ({ page }) => {
  const loginPage = new LoginPage(page);
  await loginPage.goto();

  // BasePageのメソッドを使用
  const title = await loginPage.getTitle();
  expect(title).toContain('ログイン');
});
💡 BasePageに入れるべきもの
  • 全ページ共通の要素(ヘッダー、フッター)
  • 共通のメソッド(スクリーンショット、待機)
  • ユーティリティメソッド