このところ、AIの進化によりテストツールとしてのPlaywrightが便利だという話を目にする機会が多くなってきました。実際、2025年現在GoogleトレンドでもCypressやSeleniumの検索数を上回るなど、Playwrightへの注目度が高くなっているようです。以前に当ブログでCypressについてご紹介しましたが、Playwrightも気になったので少し触ってみました。

Playwrightとは

Playwrightとは、Microsoftが開発したE2E(End-to-End)テスト自動化ツールです。Webアプリケーションの動作を実際のブラウザで自動テストでき、Chrome、Firefox、Safari(WebKit)の3つのブラウザエンジンに対応しています。

ユーザーの操作を記録してテストコードを自動生成するcodegen機能や、GitHub Actionsとの連携によるコード変更時やデプロイ時の自動テスト実行も可能で、モダンなWeb開発ワークフローに適したツールとなっています。

インストール環境

Laravelで構築されたアプリケーションのE2EテストとしてPlaywrightを導入します。Laravelアプリとは異なるディレクトリにPlaywrightをインストールすることも可能ですが、今回はプロジェクトルートにインストールします。

Laravelのテストディレクトリとしてすでにtests/が存在するため、Playwright用ディレクトリはe2e/として以下の構成となるようインストールしてゆきます。

laravel-app/
├── app/
├── config/
├── database/
├── public/
├── resources/
├── routes/
├── tests/          # PHPUnit用のテスト
├── e2e/            # Playwright用のE2Eテスト ← ここ
├── package.json
└── composer.json

Playwrightインストール

まずはインストールです。最新版のインストールにはnode.jsのバージョン20、22もしくは24が必要です。

公式の手順にそって、プロジェクトのルートディレクトリで以下のコマンドを実行します。

$ npm init playwright@latest

いくつか質問されますので、プロジェクトに合う形で指定してゆきます。

.....
Do you want to use TypeScript or JavaScript? · TypeScript
Where to put your end-to-end tests? · e2e
Add a GitHub Actions workflow? (y/N) · false
Install Playwright browsers (can be done manually via 'npx playwright install')? (Y/n) › true
.....

TypeScriptかJavaScriptか?では、今回はTypescriptを選択しました。また、Playwright用のテストケースを置くディレクトリはe2eに。

GitHub Actions workflowについては、初回は設定をシンプルに保ちたいのでfalseとしました。最後の「Install Playwright browsers」の質問では、Playwright専用のブラウザ(Chromium、Firefox、WebKit)を自動でダウンロードするかを選択できます。今回はtrueを選択して自動インストールしました。

インストールが完了すると、新しく以下のファイルが作成されます。

And check out the following files:
  - ./e2e/example.spec.ts - Example end-to-end test
  - ./tests-examples/demo-todo-app.spec.ts - Demo Todo App end-to-end tests
  - ./playwright.config.ts - Playwright Test configuration

/e2e/example.spec.tsは、テストの動作を確認するためのシンプルなサンプルテスト用のファイルです。
./tests-examples/demo-todo-app.spec.tsも同じくサンプルテストですが、Playwrightが提供する実際のTodoアプリケーションを対象とした、より実践的なデモ用のE2Eテストが書かれたファイルとなっているようです。そして設定用のplaywright.config.tsが、ルートディレクトリにインストールされています。

Playwright設定ファイル

Playwrightの動作確認をする前に、playwright.config.tsの中を少し見てみます。

.....
export default defineConfig({
  testDir: './e2e',
  /* Run tests in files in parallel */
  fullyParallel: true,
  /* Fail the build on CI if you accidentally left test.only in the source code. */
  forbidOnly: !!process.env.CI,
  /* Retry on CI only */
  retries: process.env.CI ? 2 : 0,
  /* Opt out of parallel tests on CI. */
  workers: process.env.CI ? 1 : undefined,
  /* Reporter to use. See https://playwright.dev/docs/test-reporters */
  reporter: 'html',
  /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
  use: {
    /* Base URL to use in actions like `await page.goto('/')`. */
    // baseURL: 'http://localhost:3000',

    /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
    trace: 'on-first-retry',
  },
.....

インストール時に指定した通り、テストファイルの置き場所はtestDir: './e2e'と設定されています。今のe2eディレクトリにはexample.spec.tsだけが入っており、新しいテストファイルはここに追加してゆく形ですね。

また初期設定ではコメントアウトとなっていますが、テスト内で相対パスを使う際のベースとなるbaseURLも項目として記載されています。

それ以外の主な設定として、以下のような項目が挙げられています。

  • fullyParallel:テストの並列実行
  • retries:テスト失敗時のリトライ設定
  • workers:並列実行のプロセス数
  • reporter:レポートの生成

サンプルテストを実行

では早速、サンプルテストを実行してみます。e2eディレクトリに存在するすべてのspec.tsファイルを対象にテストを実行する場合、以下のコマンドを使います。

%  npx playwright test

ファイルを指定して実行する場合は以下のいずれかで可能です。

$ npx playwright test example.spec.ts
$ npx playwright test example

コマンドを実行すると、ターミナルに以下が出力されました。

Running 6 tests using 4 workers
  6 passed (11.4s)

To open last HTML report run:

  npx playwright show-report

ヘッドレスモードでテストが実行されたようで、ブラウザも何も起動せずあっという間にテストが完了しました。ターミナルに出力されたメッセージに従って、以下のコマンドを実行します。

$ npx playwright show-report

localhost:9323でHTMLレポートが表示されました。Chrome、Firefox、Safari(webkit)でテストが実行されていますね。このレポートは、Macの場合 Ctrl+C で閉じることができます。

playwright

テストが問題なく実行されたことはわかりましたが、ブラウザが何も立ち上がらないのは少し心配ですので今度はオプションをつけて実行します。

$ npx playwright test --headed

--headedをつけて実行すると、一瞬ブラウザが立ち上がりましたがあっという間に閉じてテストが完了しました。サンプルテストなので早いというのはあるかもしれませんが、ブラウザの起動からテストが始まるまでがかなり早いように感じます。

また、テストを手動で1つづつ動かしながらブラウザでの動作も確認したいという場合は、--uiをつけて実行します。

$ npx playwright test --ui

playwrightUIモード

PlaywrightのWebUIが立ち上がり、実行するテストファイル・テスト名などを選択して実行することができます。
テストコードも下部に表示されるので、作成したテストコードの動作を確認しながら動かしたりエラー時のデバッグなどに使うと良さそうですね。

テスト失敗時

今度は失敗した場合の動作を確認します。example.spec.tsを一部編集して、エラーが起こるようにします。以下のtoHaveTitle(/Playwright/)の箇所で「アクセスしたページのタイトルに”Playwright”という文字列が含まれているか」をアサーションしていますので、”Plaaywright”とaを重複するよう書き換えてみます。

.....
test('has title', async ({ page }) => {
  await page.goto('https://playwright.dev/');

  // Expect a title "to contain" a substring.
  await expect(page).toHaveTitle(/Plaaywright/); // aを重複するように編集
});
.....

これでテストを実行してみると、ターミナルへ以下のようなエラーメッセージ出力に加え、レポートが自動で立ち上がりました。

$ npx playwright test

Running 6 tests using 4 workers
  1) [chromium] › e2e/example.spec.ts:3:1 › has title ──────────────────────────────────────────────

    Error: Timed out 5000ms waiting for expect(page).toHaveTitle(expected)

    Locator: locator(':root')
    Expected pattern: /Plaaywright/
    Received string:  "Fast and reliable end-to-end testing for modern web apps | Playwright"
    Call log:
      - Expect "toHaveTitle" with timeout 5000ms
      - waiting for locator(':root')
        9 × locator resolved to <html lang="en" dir="ltr" data-theme="light" data-has-hydrated="true" data-theme-choice="system" class="plugin-pages plugin-id-default" data-rh="lang,dir,class,data-has-hydrated">…</html>
          - unexpected value "Fast and reliable end-to-end testing for modern web apps | Playwright"


       5 |
       6 |   // Expect a title "to contain" a substring.
    >  7 |   await expect(page).toHaveTitle(/Plaaywright/);
         |                      ^
       8 | });
       9 |
      10 | test('get started link', async ({ page }) => {
        at /Users/hiro/MySite/diary/e2e/example.spec.ts:7:22

    Error Context: test-results/example-has-title-chromium/error-context.md

  2) [firefox] › e2e/example.spec.ts:3:1 › has title 
.....

playwrightサンプルテスト

次回は、Playwrightの基本的なテストコードの書き方をご紹介します。

メルマガ購読の申し込みはこちらから。

By hmatsu