⚠️

Playwright MCP で E2E テストを作ろうとしたらうまくいかなかった話

に公開

0. はじめに

CursorとPlaywright MCP と組み合わせれば“簡単に E2E が書ける”らしい

そんな噂を検証すべく、社内にE2Eテストの知見がなくいいチャンスだったので試してみたらCursorのトークンを1日で大量に消費しうまく動かなかった話です。

弊社では宅配クリーニングのサイトを運営しており、そのうちの2つでチャレンジしてみました。

対象ページ 特徴
React SPA 衣類クリーニングの注文フォーム
PHP SSR 保管クリーニングの注文フォーム

1. React SPA — 118 トークン溶かしても動かず

まずは、SPAの自社のメインのサービスの注文フォームで試してみました。
AIへの指示文

my.lenet.jp/orderにアクセスして注文完了まで完了するE2Eテストを作成してください。
サイトの構造はPlaywright MCPを使用して確認してください。
入力が必要な箇所は以下のパターンに合わせてください
預ける方法は自宅から
預ける日は選択できる
最短日を選択 預け時間は選択できる最短時間を選択
受取日・受け取り時間は自動で選択されるので未選択
オプションは未選択
その他ご要望は未選択
こちらも一緒にいかがですか?は未選択
クーポンコードは未入力
エラーが出たらエラーメッセージを見て対応する動作を都度考えて行なってください。
以上で確認画面へ行き注文完了へ
上記の内容を行うE2Eテストコードを作成する

項目 状況
生成サイクル 3 回(計 118 トークン)すべて同じ locator を出力
実行結果 静的ページのログインは成功 → 注文フォームで即タイムアウト
MCP の挙動 カレンダーコンポーネントを理解できず、セルをすべて同じ <td> と認識。
固有属性も role も拾えず locator('text="1"') などテキスト一致を乱発 → 前月セルと競合してクリック失敗

🔍 原因

最大のつまずきは、固定セレクターがほぼ無いカレンダーでした。
Playwright MCP は innerText しか頼れないため、セルを locator('text="1"') などテキスト一致で指定するコードを生成。

生成自体は「完了」と判定されましたが、実際に実行すると

  • 前月セルを誤クリック
  • 「次へ」ボタンが有効化されず先へ進めない
  • strict mode violation が連発してタイムアウト

という状況に陥り、見かけ上はテストが書けたのに動かない という結果になりました。

問題のカレンダー

🩹 応急対応

- <td>1</td>
+ <td data-testid="cal-2025-07-01">1</td>
  • data-testid を 追加

data-testid をカレンダーのセルの要素に追加しただけで、MCP が
getByTestId('cal-2025-07-01') を提案。

その結果 日付クリック できるようになったが、トークン使用量が多すぎるためここまでで断念


2. PHP SSR 保管クリーニングの注文フォーム — エラーログ貼り付けで動いた

AIへの指示文

 @https://my.lenet.jp/trial_order/cloak 
にアクセスして注文完了まで完了するE2Eテストを作成してください。
サイトの構造はPlaywright MCPを使用して確認してください。
入力が必要な箇所は以下のパターンに合わせてください
お名前 テスト太郎
フリガナ テストタロウ
電話番号 09012341234
メールアドレス ランダムな値@example.com
パスワード 123456
郵便番号 1000000 郵便番号入力後住所検索ボタンを押すこと
住所は自動入力なので何もしない
番地・建物名 1-1-1
お洋服の返却先住所 初期入力のまま
ご希望のお洋服の返却時期 初期入力のまま
お支払い方法 代金引換
クーポンコード 初期入力のまま

試行 所要ステップ 結果
初回生成 1 プロンプト label-for 完備でほぼ一発ヒット
1 回目実行 エラー箇所 4 行 strict mode violationのエラーログ を貼って再生成
2 回目実行 ボタン文言 1 行手直し MCP が存在しない文言を提案 → 次へ進む に変更
3 回目実行 完了 45 秒 で最終画面まで到達

なぜ少ない修正で済んだ?

  • 直近でフォームのリファクタリングを行なっており、すべての <input><label for> が付与 → getByRolegetByLabelText がそのまま使えた

3. 成功と失敗を分けたもの

比較軸 React SPA data-testid 追加後 PHP SSR
固定セレクター 無し あり (3) ラベル+for 完備
MCP 出力 変化せず同じ locator 新しい locator を自動生成 そのまま使用可
手動修正 なし なし(testid 追加のみ) ボタン文言 1 行
フロー完走 ×(ログインのみ) △(クリックまで) ○(45 秒)

肝は “セレクター”

AIが認識しやすいHTML構造を作っていくのが今後の課題として残った


4. 今後の方針 ― “AI が迷わないフォーム” づくり

  1. まずは UI 要素に一意な識別子を付ける

    • カレンダーの日付セルや主要ボタン、入力欄など “テストで触る場所” すべてに汎用的な data-testid を付与。
    • 具体的な命名規則はチーム内ガイドラインで統一し、実装とテストを切り離す。
  2. ラベル & アクセシビリティ属性を徹底

    • <label><input> のペアや、aria-* 属性で状態を公開。
    • これにより role / name ベースでも要素が特定できる。

さいごに

ホワイトプラスでは、ビジョンバリューに共感していただけるエンジニアを募集しています!
ネットクリーニングの「リネット」など、「生活領域×テクノロジー」で事業を展開しています。
弊社に興味がある方は、オウンドメディア「ホワプラSTYLE」をご覧ください。オンラインでのカジュアル面談も可能ですので、ぜひお気軽にお問い合わせください。

Discussion