はじめに
フロントエンドの開発が高度化する中で、UI の品質保証はますます重要になっています。その中で注目されているのが、E2E(End-to-End)テストです。
その E2E テストを効率的に行うための強力なツールが Playwright です。
この記事では、Playwright の特長的な機能の 1 つであるスクリーンショット取得機能にフォーカスし、その活用方法や実装例、メリット・デメリットについて詳しく解説します。
Playwright の導入と基本設定
インストール
- Playwright のインストール
Node.js がインストールされていることを前提とします。まだの場合は Node.js 公式サイト からインストールしてください。
# プロジェクト作成(必要に応じて)
mkdir playwright-demo && cd playwright-demo
npm init -y
# Playwright のインストール
npm install -D @playwright/test
# ブラウザのバイナリも含めて一括でインストール
npx playwright install
上記コマンドで、テストランナーと主要なブラウザ(Chromium, Firefox, WebKit)がインストールされます。
- 基本的なプロジェクト構成
Playwright を使ったテストは、以下のような構成で行うのが一般的です。
playwright-demo/
├── tests/
│ └── example.spec.ts # テストファイル
├── playwright.config.ts # 設定ファイル
└── package.json
テストファイルの例(tests/example.spec.ts)
import { test, expect } from '@playwright/test';
test('トップページが正しく表示される', async ({ page }) => {
await page.goto('https://example.com');
await expect(page).toHaveTitle(/Example Domain/);
});
- テストの実行方法
以下のコマンドで、Playwright のテストを実行できます。
npx playwright test
テストが通ると、CLI 上に結果が表示され、失敗した場合はデフォルトでログや動画、スクリーンショットが test-results/ に保存されます。
-
スクリーンショット設定の有効化(任意)
Playwright は失敗時のみ自動でスクリーンショットを保存しますが、常に取得したい場合は設定ファイルに以下を追加します。
playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
use: {
screenshot: 'on', // 'only-on-failure', 'on', 'off' が指定可能
},
});
この設定をすると、すべてのテストでスクリーンショットが取得されるようになります。
これで、Playwrightによるテストの基盤が整いました。次章では、この環境を使ってスクリーンショットを実際に取得する方法とコード例を詳しく解説していきます。
スクリーンショット機能の使い方
Playwright は、テスト実行中に画面のスクリーンショットを簡単に取得することができます。ここでは、実際にスクリーンショットを取得する方法や、用途に応じたオプションの使い方について詳しく紹介します。
- 基本のスクリーンショット取得方法
最も基本的な使い方は、ページ全体のスクリーンショットを取得する方法です。以下のように記述します。
await page.screenshot({ path: 'screenshot.png' });
このコードをテストの任意のタイミングに挿入することで、指定したファイル名でスクリーンショットが保存されます。
- フルページスクリーンショット
デフォルトでは、画面に表示されている範囲のみがキャプチャされますが、オプションを指定することでページ全体のスクリーンショットが可能です。
await page.screenshot({
path: 'fullpage.png',
fullPage: true
});
このオプションを使えば、スクロールが必要な長いページでも、全体を 1 枚の画像に収められます。
- 特定の要素だけをキャプチャする
UI の一部だけをキャプチャしたい場合は、locator や elementHandle を使って要素を指定することができます。
const logo = await page.locator('img.logo');
await logo.screenshot({ path: 'logo.png' });
または elementHandle を使った方法:
const element = await page.$('div#header');
await element?.screenshot({ path: 'header.png' });
これにより、UI の一部分に限定したスクリーンショットが取得できます。
- ファイル名の工夫とタイムスタンプ
スクリーンショットを複数保存する場合、ファイル名が重複すると上書きされてしまうため、タイムスタンプなどを付けると便利です。
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
await page.screenshot({ path: `screenshot-${timestamp}.png` });
- スクリーンショットの保存先を整理する
テストが増えるとスクリーンショットも膨大になります。保存先のフォルダを整理しておくと管理が楽になります。
await page.screenshot({ path: `screenshots/homepage.png` });
/screenshots ディレクトリをプロジェクト内に作成し、ページやケースごとに分類するのがおすすめです。
このように、Playwright では数行のコードで柔軟にスクリーンショットを取得することができます。次章では、これらのテクニックを実際のテストケースに組み込んだ具体例を紹介します。
スクリーンショット付きテストの実装例
ここでは、Playwrightで実際にスクリーンショットを活用するE2Eテストのコード例を紹介します。具体的なテストケースを使って、どのようにスクリーンショットを活用するか、どこに挿入すれば効果的かを見ていきましょう。
- テスト対象のケース:ログインページのUI検証
今回は、以下の流れをテストする例を使います。 - ログインページにアクセスする
- フォームに入力する
- ログインボタンをクリックする
- ホーム画面に遷移することを確認
- 各ステップでスクリーンショットを取得
- コード例(TypeScript)
import { test, expect } from '@playwright/test';
test('ログイン後にホーム画面が表示されること', async ({ page }) => {
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
// ログインページへアクセス
await page.goto('https://example.com/login');
await page.screenshot({ path: `screenshots/step1-login-${timestamp}.png` });
// フォームに入力
await page.fill('input[name="email"]', 'test@example.com');
await page.fill('input[name="password"]', 'password123');
await page.screenshot({ path: `screenshots/step2-filled-${timestamp}.png` });
// ログインボタンをクリック
await page.click('button[type="submit"]');
// ホーム画面の表示を確認
await page.waitForSelector('h1:has-text("ホーム")');
await page.screenshot({ path: `screenshots/step3-home-${timestamp}.png` });
// アサーション(確認)
await expect(page.locator('h1')).toHaveText('ホーム');
});
ポイント解説
- ステップごとの可視化
- 各ステップでスクリーンショットを撮ることで、どの段階でUIが崩れたか、あるいは期待通りに動作しているかを視覚的に確認できます。
- タイムスタンプ付きファイル名
- テストが毎回上書きされるのを防ぎ、履歴を保持できます。これにより、失敗時の調査が容易になります。
- waitForSelector の活用
- 画面遷移直後にスクリーンショットを撮ると、描画が完了していないことがあります。必要に応じて、要素の出現を待つことで信頼性が向上します。
- CIとの連携にも有効
GitHub ActionsやCircleCIなどでテストを自動実行する際も、失敗時にスクリーンショットが出力されると、原因分析がしやすくなります。PlaywrightはCI用の設定も充実しており、--output オプションなどで出力先を指定することも可能です。
メリットとデメリット
Playwrightでスクリーンショットを活用することには多くの利点がありますが、実際の運用ではいくつかの注意点や制限もあります。この章では、スクリーンショット付きテストのメリットとデメリットを整理して解説します。
メリット
- テスト結果を視覚的に確認できる
- スクリーンショットがあると、「何がどう表示されていたか」が目で見て分かるため、テストの成否を直感的に判断できます。
- とくに以下のようなケースに有効です
- UIが正しく描画されているか
- 非表示になるべきモーダルが残っていないか
- CSSの崩れや位置ズレの確認
- バグ報告・レビューがスムーズに
- スクリーンショットは証拠としての価値も高く、エンジニア以外の関係者(デザイナー、QA、PMなど)ともスムーズに情報共有できます。バグレポートに画像があるだけで説得力が大きく変わります。
- 回帰テストに活用できる
- 前回のスクリーンショットと比較して差分を検出する「ビジュアルリグレッションテスト」に応用可能です。Playwrightは toMatchSnapshot() による画像比較にも対応しており、UIの変更があった場合に自動で検出できます。
await expect(await page.screenshot()).toMatchSnapshot('expected-home.png');
- 開発初期でも有効
- アプリのUIがまだ不安定な段階でも、最低限の状態確認としてスクリーンショットは重宝します。検証の自動化が早期から実現できます。
デメリット
- スクリーンショットの管理が煩雑になりやすい
- 毎回のテストでスクリーンショットを出力していると、ファイルが大量に生成されます。命名規則や保存場所をしっかり決めないと、後で確認するのが難しくなります。
- テスト時間がやや長くなる
- 画像を生成・保存する処理が入るため、スクリーンショット付きのテストは実行時間がわずかに増加します。大量のテストケースを並列に走らせるような環境では注意が必要です。
- UI変更に弱い場合がある
- デザインやDOM構造が頻繁に変更されると、スクリーンショットベースのテストが壊れやすくなります。ビジュアル差分ツールと組み合わせることで緩和できますが、完全な自動化は難しい場合もあります。
- CI環境での描画不具合
- CI環境ではGPUやフォントの違いなどで描画結果がローカルと異なることがあります。これは黒いスクリーンショットが出る原因にもなります。