この動画によさそうなプロンプトが載っていました。動画自体は3分強なのですぐ見られますが、プロンプトの文面がどこにも書き起こされてなかったので、見える範囲で起こしました。

プロンプト

英語

  • You are a playwright test generator.
  • You are given a scenario and you need to generate a playeright test fot it.
  • DO NOT generate test code based on the scenario alone.
  • DO run steps one by one using the tools provided by the Playwright MCP.
  • Only after all steps are completed, emit a Playwright TypeScript test that uses @playwright
  • Save generated test file in the tests directory.
  • Execute the test file and iterate until the test passes.

6番目の末尾、@playwrightの部分は見切れていたのでわかりません・・・。

日本語

  • あなたはPlaywrightのテストジェネレーターです。
  • シナリオを受け取り、Playwrightのテストを生成してください。
  • シナリオのみからテストコードを生成しないでください。
  • Playwright MCPで提供されているツールを使用して、1ステップずつ実行してください。
  • すべてのステップが完了したら、@playwrightを使用してPlaywrightのTypeScriptテストを生成してください。
  • 生成されたテストファイルをtestsディレクトリに保存してください。
  • テストファイルを実行し、テストが成功するまで繰り返してください。

実際に試してみる

CursorのPlaywright MCPを使用して、実際に試してみます。

渡したシナリオ

やはりGherkinが良いような気がしています。

Feature: 商品検索

    Scenario: OM-1を検索して最安のショップを調べる
        When "https://kakaku.com" を開く
        And "OM SYSTEM OM-1" を検索する
        And 検索結果の一番上のものを選択
        Then 商品ページに遷移している

最終的に出力されたテスト

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

test('価格.comでOM SYSTEM OM-1を検索し、商品ページに遷移する', async ({ page }) => {
    // 1. https://kakaku.com にアクセスする
    await page.goto('https://kakaku.com');

    // 2. 検索ボックスに「OM SYSTEM OM-1」と入力する
    await page.getByPlaceholder('何をお探しですか?').fill('OM SYSTEM OM-1');

    // 3. 検索ボックス下のSubmitボタンをクリックする
    await page.getByRole('button', { name: 'Submit' }).click();

    // 4. OM SYSTEM OM-1 ボディの商品リンクをクリックする
    await page.getByRole('link', { name: 'OM SYSTEM OM-1 ボディ' }).first().click();

    // 5. 商品ページに「OM SYSTEM OM-1 ボディ」というテキストが表示されていることを確認する
    await expect(page.locator('h2', { hasText: 'OM SYSTEM OM-1 ボディ' })).toBeVisible();
}); 

テストの一部修正提案

最初に動かしたときには成功しませんでした。Cursorからは以下提案。

テストは実行されましたが、最後の検証(OM SYSTEM OM-1 ボディ というテキストの可視性確認)でエラーが発生しました。 理由は、getByText(‘OM SYSTEM OM-1 ボディ’) が4つの要素にマッチしてしまい、Playwrightのstrictモード違反となったためです。 この場合、より特定の要素(例:h1やh2、または最初の要素など)を指定することで解決できます。 どの要素で検証したいか、もしくは「最初に見つかった要素」で良いかご指示いただけますか? (例:h1の「OM SYSTEM OM-1 ボディ 価格比較」や、h2の「OM SYSTEM OM-1 ボディ」など) ご希望をお知らせください。

これを受けて、上記コードのようにh2で判断させるように変更し、無事Passするようになりました。

プロンプトの良い点

1ステップずつ実行させたうえでテストが通るように修正させているので、安定感が増しているように感じました。 また「シナリオのみからテストコードを生成しないでください」という指定と合わせて、雰囲気でそれらしいコードを出すのではなく動くものを出すことに役立っているようです。

このプロンプトはもう少し改善の余地があるかもしれませんが、とりあえずたたき台として渡す分には良いように思います。