Cursor + Playwrightでブラウザテスト自動化!Google Driveサインインを例に解説
はじめに:ブラウザテスト自動化の重要性とCursor・Playwrightの概要
ブラウザテストの課題と自動化の必要性
ブラウザを介したWebアプリケーションのテストは、現代のソフトウェア開発において避けて通れない重要な工程です。しかし、このテストを手動で行うとなると、非常に多くの時間と労力がかかります。特に、複数のブラウザやデバイスでの互換性確認、頻繁な機能追加や修正に伴う回帰テストは、手動では現実的ではありません。私は以前、手動テストの繰り返しに辟易し、もっと効率的な方法はないかと常に考えていました。
手動テストの大きな課題は、その非効率性だけではありません。人間が行う作業である以上、見落としや操作ミスといったヒューマンエラーが発生するリスクが常に伴います。また、テスト担当者のスキルや経験によって結果にばらつきが生じることもあり、テストの品質を一定に保つことが難しいという側面もあります。これらの課題を解決し、開発サイクルを加速させるためには、テスト自動化が不可欠なのです。
そこで注目されるのが、AIを活用した開発環境「Cursor」と、モダンなブラウザテスト自動化ライブラリ「Playwright」の組み合わせです。Playwrightは、Chromium、Firefox、WebKitといった主要なブラウザを単一のAPIで操作でき、高速かつ安定したテスト実行を可能にします。一方、CursorはAIがコード生成やデバッグを支援してくれるため、Playwrightのスクリプト作成を劇的に効率化できます。この二つのツールを組み合わせることで、ブラウザテスト自動化の敷居は大きく下がり、より多くのエンジニアがその恩恵を受けられるようになります。まさにブラウザのテストは大変なので自動化する手段として使っていきたいという私の動機に合致する強力なソリューションだと感じています。
CursorとPlaywrightのセットアップと基本操作
環境構築手順
まず、Playwrightを使用するための環境を整えましょう。PlaywrightはNode.js上で動作するため、Node.jsとnpm(Node.jsのパッケージマネージャー)がインストールされていることを確認します。もしインストールされていない場合は、Node.jsの公式サイトからインストーラーをダウンロードして導入してください。私の環境では、Node.jsのバージョンは18以上を使用しています。
次に、Playwrightをプロジェクトにインストールします。新しいプロジェクトを作成し、以下のコマンドを実行してください。このコマンドは、Playwrightのライブラリ本体と、テスト実行に必要なブラウザバイナリを自動的にダウンロードしてくれます。
npm init playwright@latest
このコマンドを実行すると、いくつかの質問が表示されます。TypeScriptを使用するか、テストファイルをどこに配置するか、GitHub Actionsのワークフローを追加するかなどです。基本的にはデフォルトの選択肢で問題ありませんが、ご自身のプロジェクトに合わせて適宜変更してください。これにより、package.jsonやplaywright.config.tsなどの設定ファイルが自動生成されます。
Cursorの導入は非常に簡単です。Cursorの公式サイトからアプリケーションをダウンロードし、インストールするだけです。CursorはVS Codeをベースにしているため、VS Codeに慣れている方ならすぐに使いこなせるでしょう。インストール後、Cursorを開き、先ほどPlaywrightをセットアップしたプロジェクトのフォルダを開けば準備完了です。AIの力を借りて、効率的なコーディング体験が待っています。
基本的なブラウザ操作のコード例
Playwrightを使った基本的なブラウザ操作のコード例をいくつか紹介します。CursorのAIアシスタントを活用しながら、これらのスクリプトを作成していくイメージです。
1. ブラウザを起動し、特定のURLにアクセスする
最も基本的な操作です。playwrightモジュールからchromium(またはfirefox, webkit)をインポートし、ブラウザインスタンスを起動します。page.goto()メソッドで指定したURLに遷移します。
import { test, expect } from '@playwright/test';
test('トップページにアクセスできること', async ({ page }) => {
// 指定したURLにアクセスします
await page.goto('https://www.google.com/');
// ページのタイトルが期待通りであることを確認します
await expect(page).toHaveTitle(/Google/);
});
2. 要素を特定し、テキストを入力する
検索ボックスなどの入力フィールドにテキストを入力する例です。page.locator()で要素を特定し、fill()メソッドで値を入力します。セレクタはCSSセレクタやXPathなど、様々な方法で指定できます。
import { test, expect } from '@playwright/test';
test('検索ボックスにテキストを入力できること', async ({ page }) => {
await page.goto('https://www.google.com/');
// 検索ボックス(name属性が'q'の要素)を特定し、'Playwright'と入力します
await page.locator('[name="q"]').fill('Playwright');
// 入力されたテキストが正しいことを確認します
await expect(page.locator('[name="q"]')).toHaveValue('Playwright');
});
3. ボタンをクリックし、ページ遷移を確認する
ボタンをクリックして、その後のページ遷移を確認する例です。click()メソッドで要素をクリックし、expect(page).toHaveURL()でURLが正しく遷移したかを確認します。
import { test, expect } from '@playwright/test';
test('検索ボタンをクリックして検索結果ページに遷移すること', async ({ page }) => {
await page.goto('https://www.google.com/');
await page.locator('[name="q"]').fill('Playwright');
// 検索ボタン(name属性が'btnK'の要素)をクリックします
// Playwrightは自動的に要素が見えるまで待機します
await page.locator('[name="btnK"]').first().click(); // 複数の要素がある場合first()で最初の要素を選択
// 検索結果ページに遷移したことを確認します
// URLに'search'が含まれていることを検証します
await expect(page).toHaveURL(/search/);
// 検索結果が表示されていることを確認します
await expect(page.locator('#search')).toBeVisible();
});
これらの基本的な操作を組み合わせることで、複雑なユーザーシナリオも自動化できるようになります。CursorのAIに「Googleの検索ボックスにテキストを入力して検索するPlaywrightのコードを書いて」と指示すれば、上記のようなコードを生成してくれるので、非常に効率的です。
Google Driveサインインの自動化実装例
Google Driveサインイン画面の特徴と自動化のポイント
Google Driveのサインイン画面は、そのセキュリティの高さから自動化においていくつかの注意点があります。まず、サインイン画面の構造ですが、通常はメールアドレスまたは電話番号の入力、次にパスワードの入力という2段階のフローになっています。これはセキュリティを強化するための一般的な手法です。
特に注意すべきは、2段階認証やセキュリティ対策です。Googleはユーザーのセキュリティを非常に重視しており、普段と異なる環境からのアクセスや、不審なログイン試行と判断された場合には、追加の認証(スマートフォンへの通知、バックアップコード、生体認証など)を要求することがあります。テスト自動化の文脈では、これらの追加認証フローをどのように扱うかが課題となります。テスト環境では、これらのセキュリティ機能を一時的に無効にするか、特定のテスト用アカウントを用意するなどの工夫が必要になるでしょう。
また、サインイン画面には「to continue to Google Drive」という文言が表示されることがあります。これは、ユーザーがGoogle Driveへのアクセスを意図していることを確認するためのメッセージであり、Playwrightで自動化する際には、この文言が表示されていることを確認したり、場合によっては特定のボタンをクリックして続行したりする必要があるかもしれません。この文言は、ユーザーがどのサービスにログインしようとしているのかを明確にするための重要な情報です。自動化スクリプトでは、このような画面上のテキストをアサーション(検証)に利用することも可能です。
CursorとPlaywrightでのサインイン自動化コード例
Google Driveのサインインを自動化する具体的なコード例を見ていきましょう。ここでは、メールアドレスとパスワードを入力してログインする基本的なフローを想定します。セキュリティ上の理由から、実際のメールアドレスとパスワードは環境変数などで管理することをお勧めします。
1. Googleサインインページへのアクセス
まず、Googleのサインインページにアクセスします。Google Driveへの直接リンクからサインインページにリダイレクトされることもあります。
import { test, expect } from '@playwright/test';
test('Google Driveにサインインできること', async ({ page }) => {
// Google DriveのURLにアクセスします。サインインが必要な場合、自動的にサインインページにリダイレクトされます。
await page.goto('https://drive.google.com/');
// サインインページにリダイレクトされたことを確認します(URLに'accounts.google.com'が含まれるかなど)
await expect(page).toHaveURL(/accounts.google.com/);
// 「to continue to Google Drive」のような文言が表示されていることを確認することもできます。
// await expect(page.locator('text="to continue to Google Drive"')).toBeVisible();
});
2. メールアドレス入力の自動化
サインインページでメールアドレスまたは電話番号を入力するフィールドを探し、値を入力します。通常、このフィールドはid属性やname属性で特定できます。
// メールアドレス入力フィールドを特定し、メールアドレスを入力します。
// セレクタは、実際のHTML構造に合わせて調整してください。
// 例: id='identifierId' の場合
await page.locator('#identifierId').fill(process.env.GOOGLE_EMAIL || 'your_email@example.com');
// 「次へ」ボタンをクリックします。
// 例: id='identifierNext' のボタン
await page.locator('#identifierNext').click();
// パスワード入力画面に遷移するまで待機します。
await page.waitForURL(/signin\/v2\/sl\/pwd/);
3. パスワード入力の自動化
メールアドレス入力後に表示されるパスワード入力フィールドにパスワードを入力します。
// パスワード入力フィールドを特定し、パスワードを入力します。
// 例: name='password' の場合
await page.locator('[name="Passwd"]').fill(process.env.GOOGLE_PASSWORD || 'your_password');
// 「次へ」ボタン(または「ログイン」ボタン)をクリックします。
// 例: id='passwordNext' のボタン
await page.locator('#passwordNext').click();
4. ログイン後の遷移確認
ログインが成功したことを確認します。通常はGoogle Driveのダッシュボードページに遷移することを確認します。
// Google Driveのダッシュボードに遷移したことを確認します。
// URLに'drive.google.com'が含まれ、特定の要素(例: サイドバーなど)が表示されていることを確認します。
await expect(page).toHaveURL(/drive.google.com/);
await expect(page.locator('[aria-label="Google ドライブ"]')).toBeVisible(); // Google Driveのロゴやタイトルなど
console.log('Google Driveへのサインインに成功しました!');
});
5. 全体のコード例
上記のステップをまとめたコード例です。CursorのAIに「Google DriveにサインインするPlaywrightのテストコードを書いて」と依頼すれば、このような骨組みを生成してくれるでしょう。
import { test, expect } from '@playwright/test';
test('Google Driveにサインインできること', async ({ page }) => {
// 環境変数からメールアドレスとパスワードを取得。本番運用では必ず環境変数を使用してください。
const email = process.env.GOOGLE_EMAIL || 'your_email@example.com';
const password = process.env.GOOGLE_PASSWORD || 'your_password';
// 1. Google DriveのURLにアクセスし、サインインページにリダイレクトされることを確認
await page.goto('https://drive.google.com/');
await expect(page).toHaveURL(/accounts.google.com/);
// 調査データから引用: 「to continue to Google Drive」のような文言が表示されていることを確認
await expect(page.locator('text="to continue to Google Drive"')).toBeVisible();
// 2. メールアドレスを入力し、「次へ」をクリック
await page.locator('#identifierId').fill(email);
await page.locator('#identifierNext').click();
await page.waitForURL(/signin\/v2\/sl\/pwd/); // パスワード入力画面への遷移を待機
// 3. パスワードを入力し、「次へ」をクリック
await page.locator('[name="Passwd"]').fill(password);
await page.locator('#passwordNext').click();
// 4. Google Driveのダッシュボードに遷移したことを確認
await expect(page).toHaveURL(/drive.google.com/);
await expect(page.locator('[aria-label="Google ドライブ"]')).toBeVisible(); // Google Driveのロゴやタイトルなど
console.log('Google Driveへのサインインに成功しました!');
});
トラブルシューティングとベストプラクティス
ブラウザテスト自動化では、予期せぬエラーや不安定な挙動に遭遇することがよくあります。ここでは、実務で役立つトラブルシューティングとベストプラクティスを紹介します。
よくあるエラーと対処法
- セレクタが見つからない (Element not found): WebサイトのHTML構造は頻繁に変わることがあります。Playwrightの
page.locator()で指定しているセレクタが、現在のページのHTMLと一致しているかを確認してください。開発者ツールで要素を検証し、最も安定したセレクタ(id属性やユニークなdata-testid属性など)を使用することが重要です。 - 要素がクリックできない/入力できない (Element not interactable): 要素がまだロードされていない、または他の要素に隠れている可能性があります。Playwrightはデフォルトで要素が見えるまで待機しますが、明示的に
page.waitForSelector()やpage.waitForLoadState('networkidle')などを使って待機時間を設けることも有効です。また、force: trueオプションを使って強制的に操作することもできますが、これは最終手段と考えるべきです。 - タイムアウトエラー (Timeout exceeded): ページ遷移や要素の出現に時間がかかりすぎている場合に発生します。
page.setDefaultTimeout()でグローバルなタイムアウト時間を調整するか、特定の操作に対して{ timeout: 10000 }のように個別にタイムアウトを設定できます。
テストの安定性向上のための工夫
- 環境変数の活用: ログイン情報やテストデータなど、機密性の高い情報や環境によって異なる値は、コードに直接書き込まず、環境変数として管理しましょう。これにより、セキュリティが向上し、異なる環境でのテスト実行が容易になります。
- リトライ戦略の導入: ネットワークの遅延や一時的なUIの不安定さによってテストが失敗することがあります。Playwrightにはリトライ機能が組み込まれており、
playwright.config.tsでretries: 2のように設定することで、失敗したテストを自動的に再実行させることができます。 - テストデータの分離: テストごとに独立したデータを使用することで、テスト間の依存関係をなくし、テストの信頼性を高めます。テスト開始時にデータをセットアップし、テスト終了後にクリーンアップする「セットアップ/ティアダウン」のパターンを導入しましょう。
セキュリティ面の注意点
- 本番環境での自動テストの実行は慎重に: 特にログインを伴うテストは、本番環境で実行すると意図しないデータ変更やアカウントロックなどのリスクがあります。可能な限りステージング環境やテスト環境で実行するようにしてください。
- 機密情報の取り扱い: ログイン情報などの機密データは、バージョン管理システムにコミットしないように細心の注意を払ってください。環境変数や安全なシークレット管理サービスを利用することが必須です。
- 2段階認証の回避策: Googleのようなサービスでは2段階認証が必須の場合が多いです。テスト用アカウントでは2段階認証を無効にするか、特定のIPアドレスからのアクセスを許可するなどの設定を検討してください。ただし、これはセキュリティリスクを伴うため、慎重な判断が必要です。
まとめと今後の展望
今回の内容の振り返り
本記事では、CursorとPlaywrightを組み合わせたブラウザテスト自動化の基本的な実装方法について解説しました。手動テストの非効率性やヒューマンエラーのリスクを克服するために、テスト自動化がいかに重要であるかを改めて認識いただけたかと思います。Playwrightの高速かつ安定したブラウザ操作能力と、CursorのAIによるコード生成支援は、テストスクリプト作成の生産性を飛躍的に向上させます。
特に、Google Driveのサインイン自動化を例に、具体的なコード例と実装のポイントを詳しく見てきました。メールアドレスやパスワードの入力、ログイン後のページ遷移確認といった一連のフローを自動化することで、複雑なWebアプリケーションのログイン機能も効率的にテストできることを示しました。また、Googleのサインイン画面が持つセキュリティ上の特徴や、「to continue to Google Drive」のような文言の重要性についても触れ、実践的な自動化のヒントを提供できたと自負しています。
今後のブラウザテスト自動化の可能性
CursorとPlaywrightの組み合わせは、ブラウザテスト自動化の未来を大きく変える可能性を秘めています。AIの進化は止まることを知らず、Cursorのようなツールは今後さらに賢くなり、より複雑なテストシナリオの自動生成や、テスト失敗時の原因分析まで支援してくれるようになるでしょう。これにより、エンジニアやQA担当者は、より本質的なテスト設計や品質向上に注力できるようになります。
私自身も、この技術の進化には大きな期待を寄せています。今後、AIがテストコードを自動で修正したり、UIの変更に自動で追従したりする機能が一般化すれば、テストメンテナンスのコストも大幅に削減されるはずです。ブラウザテスト自動化は、単なる作業の効率化に留まらず、ソフトウェア開発全体の品質とスピードを向上させるための強力なドライバーとなるでしょう。ぜひ、今回学んだ知識を活かし、ご自身のプロジェクトでCursorとPlaywrightを使ったテスト自動化に挑戦してみてください。きっと、その効果に驚かれることと思います。