開発tax-lpメモ
Playwright E2Eテストでコンタクトフォームを全業種検証する
LPプロジェクトのお問い合わせフォームにPlaywright E2Eテストを導入した日。全業種でフォーム送信が正しく動くことを自動検証する仕組みを作った。
背景
全業種のフォームを手動確認すると1業種あたり2〜3分、全体で20分以上かかる。改修のたびにこれを繰り返すのは現実的でないのでテストを自動化した。
テストを2層に分けた:
- E2Eテスト(Playwright): ブラウザ上でのフォーム入力・送信・完了画面表示
- API統合テスト:
/api/contactエンドポイントへのPOST、メール送信結果
セットアップのポイント
- Chromiumのみインストール(クロスブラウザは優先度低)
fullyParallel: falseでレート制限対策(後述)screenshot: 'only-on-failure'で失敗時のみスクリーンショットwrangler pages dev distで本番に近い構成でテスト
業種の切り替えは X-Subdomain カスタムヘッダーでシミュレート。サーバーミドルウェア側でヘッダーを優先的に使う処理を追加した。
Resend APIのレート制限との戦い
全業種を連続テストすると、Resendの無料プランの制限(2リクエスト/秒)に引っかかり、429が散発的に返る。
3段階の対策
- テスト間ウェイト:
beforeEachで600msのスリープ - サーバー側リトライ: 指数バックオフ + ジッターで429発生時に自動回復。テストだけでなく本番でも有効
- 直列実行:
workers: 1で同時リクエストを防止
3つの組み合わせで全業種のテストが安定した。
テスト失敗からの学び
失敗スクリーンショットとトレースから根本原因を特定するサイクルを何度も回した。
- 完了画面が出ない: Resend 429 → リトライ未実装でサーバー500 → タイムアウト
- バリデーション不安定: Vueハイドレーション完了前のクリック →
networkidle待機を追加 - 文字化け: HTMLメールに
charset="utf-8"が未指定 → メタタグ追加で解決
日本語メールの文字化け対策
Resend APIに送るHTMLメールに <meta charset="utf-8"> を追加。古いメールクライアント向けに <meta http-equiv="Content-Type"> も併記。
あわせてユーザー入力のHTMLエスケープ関数を追加(XSS対策)。テストを書く過程で抜けに気づけた。
最終結果
全26テスト pass(52秒)。直列実行で時間はかかるが、手動テスト20分と比べれば十分。
学び
- Resendの2リクエスト/秒制限はテスト連続実行で容易に引っかかる。指数バックオフはテストと本番両方で効く
- Playwright の
screenshot: 'only-on-failure'+trace: 'on-first-retry'で失敗分析の材料が自動で残る - テストを書く過程でXSS脆弱性や文字化けなど本番の問題を発見できた