🫡

PlaywrightとGitHubActionsでCI環境構築

に公開

TL;DR

Playwright公式のサンプルを参考に、GitHub ActionsでPlaywrightテストを実行する最小構成を作りました。

実際のコードがこちら。

test.yaml

name: Playwright Tests
on:
  push:
    branches: [ main, master ]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - uses: actions/setup-node@v4
    - run: npm ci
    - run: npx playwright install --with-deps
    - run: npm run test

きっかけ:E2Eテストって環境構築が面倒そう

PlaywrightでE2Eテストを書いたことはありましたが、CIに載せたことがありませんでした。

「Playwrightって最近よく聞くけど、どう始めればいいんだろう...」

興味はあったものの、なかなか手が出せずにいました。

CI環境構築の壁

E2Eテストを導入しようと思った時の懸念:

  • ブラウザのインストール: Chrome, Firefox, Safariをどう用意する?
  • CI設定: GitHub Actionsでどう動かす?
  • テストの書き方: どんなAPIがあるの?

Playwrightの基本概念

実装の前に、Playwrightの特徴を理解しておきましょう。

Playwrightとは?

Microsoft製のE2Eテストフレームワーク。特徴は:

  • 複数ブラウザ対応: Chromium, Firefox, WebKit(Safari)
  • 高速: 並列実行が標準でサポート
  • 自動待機: 要素が表示されるまで自動で待つ
  • TypeScript完全サポート: 型安全にテストが書ける

テストの書き方

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

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

  // ページタイトルをチェック
  await expect(page).toHaveTitle(/Playwright/);
});

pageオブジェクトでブラウザを操作するだけのシンプルな構成

プロジェクト構成

今回作った最小構成のディレクトリ:

playwright-github-actions-ci/
├── .github/
│   └── workflows/
│       └── playwright.yml    # GitHub Actions設定
├── tests/
│   └── example.spec.ts       # サンプルテスト
├── playwright.config.ts      # Playwright設定
├── package.json
├── LICENSE                   # MIT
└── README.md

必要最低限。 これだけでCI環境が動きます。(LICENSEは不要です)

実装:各ファイルの役割を理解しながら構築

1. package.json - 依存関係とスクリプト

{
  "name": "playwright-github-actions-ci",
  "version": "1.0.0",
  "description": "Minimal CI setup for running Playwright tests on GitHub Actions",
  "scripts": {
    "test": "playwright test"
  },
  "keywords": ["playwright", "github-actions", "ci", "testing"],
  "license": "MIT",
  "devDependencies": {
    "@playwright/test": "^1.40.0"
  }
}

ポイント

  • @playwright/testだけ: 余計な依存関係なし
  • npm testでテスト実行: シンプルなコマンド
  • MIT License: 商用利用も可能

2. playwright.config.ts - テスト設定

import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  testDir: './tests',
  fullyParallel: true,
  forbidOnly: !!process.env.CI,
  retries: process.env.CI ? 2 : 0,
  workers: process.env.CI ? 1 : undefined,
  reporter: 'html',
  use: {
    trace: 'on-first-retry',
  },

  projects: [
    {
      name: 'chromium',
      use: { ...devices['Desktop Chrome'] },
    },
  ],
});

設定の意味

オプション 説明
testDir テストファイルの場所
fullyParallel テストを並列実行
forbidOnly CI環境で.onlyを禁止(.onlyがついているとそれしか実行しないのでテスト漏れ防止のため)
retries CI環境では2回リトライ
workers CI環境では1ワーカー(安定性重視)
reporter HTMLレポート生成
trace 失敗時のトレース記録

CI環境では安定性を重視。 ローカルでは速度優先。
また今回はテストのためChromeのみを対象としています。

3. テストコード(tests/example.spec.ts)

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

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

  await expect(page).toHaveTitle(/Playwright/);
});

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

  await page.getByRole('link', { name: 'Get started' }).click();

  await expect(page.getByRole('heading', { name: 'Installation' })).toBeVisible();
});

テストの流れ

  1. ページ遷移: page.goto()でURLを開く
  2. 要素の取得: getByRole()でアクセシブルに要素を取得
  3. アクション: click()でクリック
  4. アサーション: expect().toBeVisible()で検証

アクセシビリティを考慮。 getByRole()を使うことで、ユーザーの視点でテストを書ける。

4. GitHub Actions設定(.github/workflows/playwright.yml)

name: Playwright Tests
on:
  push:
    branches: [ main, master ]
  pull_request:
    branches: [ main, master ]
jobs:
  test:
    timeout-minutes: 60
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - uses: actions/setup-node@v4
      with:
        node-version: lts/*
    - name: Install dependencies
      run: npm ci
    - name: Install Playwright Browsers
      run: npx playwright install --with-deps
    - name: Run Playwright tests
      run: npm run test
    - uses: actions/upload-artifact@v4
      if: always()
      with:
        name: playwright-report
        path: playwright-report/
        retention-days: 30

ワークフローの流れ

1. チェックアウト
   ↓
2. Node.js環境セットアップ(LTS版)
   ↓
3. npm ci(依存関係インストール)
   ↓
4. Playwrightブラウザインストール
   ↓
5. テスト実行
   ↓
6. レポートをArtifactとして保存(失敗時も)

重要なポイント

- name: Install Playwright Browsers
  run: npx playwright install --with-deps

--with-depsが重要。 これでブラウザの依存ライブラリも一緒にインストールされます。

- uses: actions/upload-artifact@v4
  if: always()

if: always()で失敗時もレポート保存。 デバッグに必須。

実際に動かしてみる

1. セットアップ

# リポジトリクローン
git clone https://github.com/yourusername/playwright-github-actions-ci.git
cd playwright-github-actions-ci

# 依存関係インストール
npm install

# Playwrightブラウザインストール
npx playwright install

2. ローカルでテスト実行

# ヘッドレスモードで実行
npm test

# ブラウザを表示して実行
npx playwright test --headed

# UIモードで実行(デバッグに便利)
npx playwright test --ui

3. CI環境で実行

GitHubにpushするだけ:

git add .
git commit -m "Add Playwright tests"
git push origin main

GitHub Actionsが自動で:

  1. テストを実行
  2. 結果をレポート
  3. Artifactに保存

4. テストレポートの確認

GitHub Actionsのワークフロー実行画面から:

  1. 実行したテストを確認
  2. Artifactをダウンロード
  3. HTMLレポートを開く

GitHub Actions Artifacts

つまずいたポイント

特になし!公式ドキュメントが優秀

Playwrightの公式ドキュメントが非常に充実していて、ほとんど迷いませんでした。

強いて言えば:

  • 初回ブラウザインストールに時間がかかる: Chromium, Firefox, WebKitの3つで数GB
  • CI環境では--with-deps必須: これを忘れると依存エラーになる

学んだこと

技術面

  • Playwrightは簡単: セットアップが非常にシンプル
  • CI設定も簡単: 公式のGitHub Actions設定がそのまま使える

CI/CD設計

  • Artifactの活用: 失敗時のレポート保存が重要
  • リトライ設定: CI環境では不安定なテストに備える
  • 並列実行: テストが増えても高速

まとめ:Playwrightは始めやすい

今回、最小構成でPlaywright CI環境を構築してみて、思った以上に簡単でした。

今後

  • 初回ブラウザインストールに時間がかかるので、回避策の模索
    • これだけシンプルでも3分かかったので
  • vitestなどのテストランナーとの併用

今回作ったもの: playwright-github-actions-ci

E2Eテストを始めたい人の参考になれば嬉しいです。

Discussion