Pantherでスクリーンショット&デバッグ自動化|PHP製E2Eテスト環境を完全ガイド
PHP だけで実ブラウザを操作し、E2E テストからスクリーンショットまで自動化できる Symfony Panther。
この記事では takeScreenshot()
によるキャプチャ取得の基本から、ネットワークログや JS エラーの収集、Zenstruck/Browser の連携、CI/CD への統合方法まで、現場で使えるテクニックを網羅的に解説します。
「テストは通るのに本番で動かない」を防ぎたい開発者必見のガイドです。
Pantherとは?E2Eテストとスクリーンショットの基礎
Symfony Panther は W3C WebDriver をラップし、PHP だけで実ブラウザ操作を自動化できる E2E テストライブラリです。
ユニットテストでは見逃しがちなルーティング設定ミスや JavaScript エラーを、本番同様の画面で再現しながら検証できます。
Slim や Laravel などフレームワークを問わず導入でき、CI ではヘッドレス実行、ローカルでは GUI を表示してステップデバッグ、といった柔軟な運用も容易です。
さらに takeScreenshot()
による PNG 取得や、コンソールログ・ネットワークログの収集 API を備えており、失敗時の再現資料を自動で蓄積できます。
こうした仕組みのおかげで MTTR(平均復旧時間)を短縮し、ユーザー体験を守ることが可能になるのです。
takeScreenshot()の仕組みとベストプラクティス
Client::takeScreenshot()
は PNG バイナリを文字列で返す メソッドです。第一引数にファイルパスを渡せば即時保存も行えます。
バイナリをそのままレポートに埋めこむ場面では base64_encode()
を併用すると扱いやすくなるでしょう。
$client = Client::createChromeClient();
$client->request('GET', '/dashboard');
// ファイルへ保存
\$client->takeScreenshot('var/tests/dashboard.png');
// 文字列をBase64へ変換し、Slack通知へ添付
\$raw = \$client->takeScreenshot();
\$base = base64\_encode(\$raw);
注意点: Base64 文字列を直接返すわけではありません。必ず base64_encode()
を挟んでください。
失敗時の自動キャプチャ:Zenstruck/Browser編
Panther 本体には “テスト失敗時に自動でスクリーンショットを保存する” ヘルパは存在しません。代替として広く使われているのが zenstruck/browser
です。
このライブラリの HasBrowser
トレイトは、テスト失敗をフックして HTML・JS コンソールログ・スクリーンショットをまとめて var/browser/
以下に出力します。
導入は composer require zenstruck/browser で可能で、既存の Panther テストをほぼ変更せずデバッグ効率を高められます。
全画面キャプチャを撮るテクニック
デフォルトの takeScreenshot()
はビューポートのみ撮影します。縦に長い LP や管理画面をまるごと残したい場合は、DOM の高さを取得してウィンドウサイズを動的に拡張する方法が実用的です。
$height = $client->executeScript('return document.documentElement.scrollHeight');
$width = $client->executeScript('return document.documentElement.scrollWidth');
$client->manage()->window()->setSize(new WebDriverDimension($width, $height));
$client->takeScreenshot('fullpage.png');
ウィンドウリサイズ後に再読み込みを挟むと要素の再描画が安定します。
また、JavaScript による動的描画を確実にキャプチャするには、リサイズ直後に usleep()
や waitFor()
を用いた少しの待機を入れるのが効果的です。
スクリーンショット&動画撮影ツール比較表
手法 | 実装難易度 | 撮影範囲 | メリット | 課題 |
---|---|---|---|---|
Panther takeScreenshot() | 低 | ビューポート | 標準機能で完結 | 長尺ページは不可 |
Panther+window拡張 | 中 | 全画面 | 追加ライブラリ不要 | 動的高さの計算が必要 |
Zenstruck/Browser | 中 | ビューポート | 失敗時にHTMLと一括保存 | 依存が増える |
Playwright video: ‘retain-on-failure’ | 中 | 動画 | 操作を丸ごと記録 | PHP で扱うには Node.js 側で撮影後、 アーティファクトへ手動コピーが必要 |
PHP 連携では npx playwright test
で動画を生成し、GitHub Actions の actions/upload-artifact
で取得する運用が一般的です。
ブラウザオプションとヘッドレス切り替え
Client::createChromeClient(?string $driver=null, ?array $arguments=[], …)
の 第二引数 $arguments には Chrome 起動フラグを配列で渡せます。
GUI デバッグを行う場合は '--no-headless'
を指定すると意図がより明確です。ヘッドレス版の新実装 '--headless=new'
は Chromium のバージョン依存で動作差があり、チームメンバーの環境をまたいで再現性を保つなら “no-headless + 可視化” を推奨します。
また Docker や CI で権限エラーが出た際は PANTHER_NO_SANDBOX=1
を組み合わせると解消しやすいです。
コンソール・ネットワークログ取得テクニック
スクリーンショットと並行して JS エラーや XHR 失敗を監視すると、問題発見の精度が上がります。Panther クライアントは $client->manage()->getLog('browser')
でコンソールログを、'performance'
種別でネットワークログを取得可能です。
※ 'performance'
ログの取得には、ブラウザおよびドライバ側で該当ログタイプが有効化されている必要があります。CI 環境では取得できないケースもあるため、事前に getAvailableLogTypes()
で確認するのが安全です。
失敗テストの後処理でまとめて JSON 化し、S3 や MinIO へアップロードすると時系列で比較しやすくなります。
CI/CDパイプラインへの統合例(GitHub Actions)
- name: Run E2E tests
run: vendor/bin/phpunit --testsuite=e2e
* name: Upload artifacts on failure
if: failure()
uses: actions/upload-artifact\@v4
with:
name: panther-artifacts
path: |
var/browser # Zenstruck/Browser
var/tests # 独自スクショ
失敗ジョブのみアーティファクトを保存すればストレージコストを抑えつつ、スクリーンショット・HTML・コンソールログを即時確認できます。
Slack 通知にアーティファクト URL を添付すると、開発者がローカルで再現せずとも状況を把握しやすくなるでしょう。
まとめ:スクリーンショットデバッグで品質と開発速度を両立
Panther は PHP だけでリアルブラウザを操り、takeScreenshot()
やログ取得 API により “見える化” を簡単に実装できます。
Zenstruck/Browser と組み合わせれば失敗時の artefact 収集が自動化され、CI でのトラブルシュートが加速します。
さらに Playwright の動画記録や DOM 高さに応じた全画面キャプチャを取り入れれば、ユーザー視点での挙動を立体的に検証できます。
スクリーンショットは「結果の証拠」であると同時に、開発者同士の共通言語です。この記事で紹介したテクニックを活用し、リグレッションバグの早期発見と MTTR の最小化を実現してください。