
GitHub Actions ではじめる Playwright E2E CI
GitHub Actions で Playwright を動かし、結果をレポート & ブランチ保護まで設定
初回公開日
最終更新日
前回のおさらい
まだ読んでいない方は
はじめての Playwright ─ “録画” で体験する E2E テスト入門
でローカル録画 → 実行を体験してみてください。
本記事はその「続編」で、ローカルで動かしたテストを GitHub Actions に載せる のがゴールです。
まだ読んでいない方は
はじめての Playwright ─ “録画” で体験する E2E テスト入門
でローカル録画 → 実行を体験してみてください。
本記事はその「続編」で、ローカルで動かしたテストを GitHub Actions に載せる のがゴールです。
0. この記事で得られるもの
💡 やること | 💪 得られるメリット |
---|---|
GitHub Actions で Playwright を自動実行 | push / PR ごとに “壊れていない” を機械が保証 |
HTML レポート をアーティファクト添付 | 失敗したスクショや diff をチーム全員が確認 |
ブランチ保護ルールを設定 | テストが緑 ✓ でないと main にマージ不可 → 品質ゲート完成 |
1. 前提:ローカルで E2E テストが動く状態
- Next.js + shadcn/ui のフォーム例を使っている(前回記事サンプル)
簡単なフォームサンプルをGitHubに用意してありますので、そちらを利用いただくとこの記事と同様の体験が可能です。
上記を利用する場合は下記を実行してください。
zsh
1# クローン生成(本記事用のディレクトリへ)
2git clone https://github.com/delogs-jp/playwright-e2e.git playwright-ci
3cd playwright-ci
4
5# 依存インストール(Playwright はまだ入っていない)
6npm install

2. Playwrightとテストファイルの準備
この節ははじめての Playwright ─ “録画” で体験する E2E テスト入門 と重複する部分です。さらりと記述します。
今回はテストパターンは「スクリーンショット差分でレイアウト崩れを検知」と「正常パターンだけすばやくテスト」の2パターンを用意します。
Playwrightのインストール
zsh
1npm i -D @playwright/test
2npx playwright install # ブラウザバイナリを一括取得
スクリーンショット差分でレイアウト崩れを検知するテストファイルの作成
tests/contact-visual.spec.ts
というファイルを下記内容で作成します。ts : contact-visual.spec.ts
1import { test, expect } from "@playwright/test";
2
3test("お問い合わせフォームのレイアウト", async ({ page }) => {
4 await page.goto("/"); // playwright.config.tsでBaseurlを指定するのでパスだけ指定
5 await page.setViewportSize({ width: 1280, height: 720 });
6
7 await expect(page).toHaveScreenshot("contact-baseline.png", {
8 threshold: 0.01, // 許容差分 1%
9 });
10});
フォームの正常パターンだけテストするテストファイルの作成
tests/contact-happy.spec.ts
というファイルを下記内容で作成します。ts : contact-happy.spec.ts
1import { test, expect } from "@playwright/test";
2
3test("お問い合わせフォーム 正常送信", async ({ page }) => {
4 await page.goto("/"); // playwright.config.tsでBaseurlを指定するのでパスだけ指定
5
6 await page.getByLabel("お名前").fill("テスト太郎");
7 await page.getByLabel("メールアドレス").fill("taro@example.com");
8 await page.getByLabel("お問い合わせ内容").fill("Playwright の動作確認です。");
9
10 await page.getByRole("button", { name: "選択してください" }).click();
11 await page.getByRole("option", { name: "質問" }).click();
12
13 await page.getByRole("button", { name: "送信" }).click();
14
15 await expect(page).toHaveURL(/\/thanks/);
16 await expect(
17 page.getByRole("heading", { name: "送信ありがとうございました" })
18 ).toBeVisible();
19});
2. Playwright に “webServer” を設定
CI では 「サーバーを立てる → テスト → 自動終了」 が理想。
プロジェクト直下に
プロジェクト直下に
playwright.config.ts
を作成して下記を記述します。ts : playwright.config.ts
1import { defineConfig } from "@playwright/test";
2import path from "path";
3
4const PORT = 3010; // ローカルと CI で共通ポート
5
6export default defineConfig({
7 testDir: "./tests",
8 retries: 1,
9
10 use: {
11 baseURL: `http://localhost:${PORT}`, // テストファイルで指定するのは面倒なので
12 },
13
14// すべてのスナップショットに共通のテンプレート
15 snapshotPathTemplate:
16 "{testDir}/__screenshots__/{testFilePath}/{arg}{ext}",
17
18// スナップショットの差分を検知-テストファイル側の設定が優先されるが、この設定がデフォルトに
19// この設定がないと、完全一致しないとNGになってしまう
20expect: {
21 toHaveScreenshot: {
22 /* 1.5% まで許容(必要に応じて微調整) */
23 maxDiffPixelRatio: 0.015, // 0.015 = 1.5 %
24 },
25 },
26
27 /* サーバーを自動起動 */
28 webServer: {
29 command: `npm run dev -- -p ${PORT}`, // Next.js を 3010 で起動
30 port: PORT,
31 reuseExistingServer: !process.env.CI,
32 },
33});
port
… ローカルで複数のプロジェクトを立ち上げたときにポートが重複して、実行エラーになるのを避けるために使わなそうなポートを指定baseURL
… テストファイルで指定するのは面倒なのでここで指定。useブロックで指定command
… 開発ビルドでも本番ビルドでも OKreuseExistingServer
… CI 上では常に fresh、ローカルは再利用で時短
3. GitHub Actions ワークフローを作成
プロジェクト直下に
text
1.github/
2└─ workflows/
3 └─ playwright.yml
.github/workflows/playwright.yml
playwright.yml
(最小構成+レポート出力)
yml : playwright.yml
1name: E2E (Playwright)
2
3on: [push, pull_request]
4
5jobs:
6 e2e:
7 runs-on: ubuntu-latest
8
9 steps:
10 # 1) ソース取得
11 - uses: actions/checkout@v4
12
13 # 2) Node 環境
14 - uses: actions/setup-node@v4
15 with:
16 node-version: 22.17.0
17
18 # 3) 依存をインストール(Playwright の JS 本体もここで入る)
19 - run: npm ci
20
21 # 4) Playwright ブラウザ & 依存ライブラリをインストール
22 - name: Install Playwright browsers
23 run: npx playwright install --with-deps
24
25 # 5) TypeScript 型チェック
26 - run: npx tsc --noEmit
27
28 # 6) Playwright テスト(HTML レポート)
29 - run: npx playwright test --reporter=html
30
31 # 7) レポートをアーティファクト化(失敗しても必ず実行)
32 - uses: actions/upload-artifact@v4
33 if: always() # ← 失敗しても必ず実行
34 with:
35 name: playwright-report # 名前は自由(日本語も可)
36 path: playwright-report # フォルダ or ファイルを指定
37 retention-days: 3 # 保存日数(最大 90 日)
38
39 # 8) Next.js 本番ビルド(任意だが品質ゲートに有益)
40 - run: npm run build
補足:
ステップ | 役割 |
---|---|
npx playwright install --with-deps | Playwright ブラウザ & 依存ライブラリをインストール |
--reporter=html | 失敗スクショ & diff が HTML で閲覧可能 |
アーティファクト | 失敗調査・デザイナー共有に便利。期限は retention-days で調整 |
アーティファクトとは?
これは今回はじめて出てきた言葉です。これは、CI の実行が終わったあとにも“手元に残しておきたいファイル” をGitHub が一時的に保管してくれる仕組み です。
- GitHub Actions の “アーティファクト” に関する主な制限と動き
項目 | 仕様 | 詳細・補足 |
---|---|---|
アップロードできるサイズ | 1アーティファクト最大 ≈ 2 GB 1ワークフロー実行あたり総量 10 GB | これは actions/upload-artifact が内部で 2 GB を上限にチャンク転送しているためです(公式 README より)。巨大ファイルは分割か圧縮を推奨します。 |
リポジトリ/アカウントごとのストレージ枠 | プライベート・リポジトリはプラン別枠に加算される 例:GitHub Free は 500 MB、Team は 2 GB など | パブリック・リポジトリは課金対象外(実質無制限)。枠を超えると 新しいアップロードが失敗 し、枠を空けるか支払い上限を上げるまで保存できません。 |
保持期間 (retention) | デフォルト 90 日 公開Repo:1-90 日 非公開Repo:1-400 日 | upload-artifact の retention-days 入力や、リポジトリ/組織設定で変更可能。 |
自動削除タイミング | 期間を過ぎたアーティファクトは自動パージされる | 削除・期限切れによる空き容量反映は 6〜12 時間ごと に更新 |
古いものから勝手に消えるか? | いいえ(キャッシュとは挙動が違う) | 保存枠に上限があるのは 総量。超過すると“最新アップロードが失敗”するだけで、古いアーティファクトは手動または retention 期限で消さない限り残ります。 対して actions/cache は総量 10 GB を超えると 最終アクセスが古い順 に自動破棄される |
古いものから勝手に消えるわけではないので、
retention-days
でプロジェクトに合わせた適切な期間を指定する必要があります。容量を超えるとエラーになってテスト実行ができなくなってしまいます。4. レイアウト崩れを検知用に一度テスト実行
レイアウト崩れを検知するには、ベースラインとなるキャプチャーが必要になります。これは一度ローカルでテスト実行することでキャプチャーが
tests/
配下に作成されるので、それを一緒にPushすることで、Git Actions でnpx playwright test --reporter=html
を実行するだけで差分チェックが可能になります。zsh
1npx playwright test tests/contact-visual.spec.ts --reporter=html --update-snapshots
ついでに、フォームの正常終了側もあわせてテストして、テスト設定に不具合がないかチェックしておきます。
zsh
1npx playwright test --reporter=html
上記のように(yamlファイルに記載したコマンドですが)テストファイルを指定しないと
tests/
配下のファイルをすべてテストしてくれます。5. Push → Actions が走るか確認
GithubのリポジトリにPushします。下記は当サイトの環境にPushする例ですが、接続設定部分については皆さんの環境にあわせて変更してください。
zsh
1# ご自分の環境に合わせてGit Hubに接続
2git remote set-url origin git@github-delogs:delogs-jp/playwright-ci.git
3
4# 全てステージしてコミット
5git add .
6git commit -m "ci: Add Playwright E2E workflow"
7
8git push -u origin main
- Actions タブ に “E2E (Playwright)” が生成 → ジョブ進行中
- 数分後に 緑 ✓ なら成功
playwright-report
アーティファクトをダウンロード →index.html
を開くとローカルと同じ UI

- レポートのダウンロードの場所が少しわかりづらいのですが、上図の該当ワークフローをクリックして詳細を開き、詳細画面の下部にあります。下図の赤丸の場所です。

6. ブランチ保護で「緑 ✓ 以外はマージ不可」に
過去記事(GitHub設定編:最小構成 CI)と同じ手順ですが、
対象リポジトリの Settings → Branchesを開き 「Add classic branch protection rule」をクリック して下図のようにします。
対象リポジトリの Settings → Branchesを開き 「Add classic branch protection rule」をクリック して下図のようにします。

- Branch name pattern:
main
- Require a pull request before mergingにチェック(任意)
- Require status checks to pass before mergingにチェック
- Require status checks…:
e2e
を選択 - 下部のCreateボタンをクリック
これで テストが赤 × の PR はマージできない 安全ゲートが完成。
7. 失敗を体験 → 修正フロー
はじめての Playwright ─ “録画” で体験する E2E テスト入門 と同様にレイアウトのチェックでエラーを起こしてしっかり動くかを検証してみます。
過去記事(GitHub設定編:最小構成 CI)と同じ手順なので、項目だけ記述しておきます。
- ブランチを作成
git switch -c feature/error-sample
- フォームのボタン
className="my-4"
→my-[999px]
に変えて、Pushgit push -u origin feature/error-sample
- Actions が赤 × → 差分スクショ付きレポート
- 修正コミット → Push → 緑 ✓ → PR → マージ
チームメンバー全員が「壊したら赤 ×、直したら緑 ✓」を体験できます。
参考リンク
この記事の執筆・編集担当
DE
松本 孝太郎
DELOGs編集部/中年新米プログラマー
ここ数年はReact&MUIのフロントエンドエンジニアって感じでしたが、Next.jsを学んで少しずつできることが広がりつつあります。その実践記録をできるだけ共有していければと思っています。
▼ 関連記事
はじめてのPlaywright-"録画"で体験する E2E テスト入門
ボタンをクリックしているだけで、テストが自動生成。『壊れてないか?』を毎回手動で確かめる作業とおさらば
2025/7/15公開

GitHub設定編:最小構成の CI を動かすまで
GitHub Actions を使った CI(継続的インテグレーション)の最小構成 を体験
2025/7/10公開

Git基本コマンド10選 -はじめてのバージョン管理で開発を加速
これからGitを使い始めるフロントエンド/バックエンド開発者向けに少しだけGitコマンドをDeep Dive
2025/7/9公開

GitHub超入門-アカウント作成から初pushまでゆっくりガイド
GitHubは「見るだけ。DLするだけ」からの卒業を目指して、利用しながら理解する第一歩の記録
2025/7/7公開

Cursorエディタの設定-Tailwind CSS 公式プラグインの設定
Tailwind CSSを快適に利用するための公式プラグインの導入についてのまとめ
2025/7/4公開
