mcpField
W
webapp-testing

webapp-testing

github.com/curiositechテスト・品質257174 回インストール1 日前に更新
リポジトリ

webapp-testing について

ブラウザーでローカルWebアプリをテストするPython Playwrightスクリプトの作成を支援するスキルです。エンドツーエンドやUIのテストに加え、フォーム検証、スクリーンショット、ブラウザーログの取得と、セレクターや待機方法を扱います。

主な機能

  1. 01Python Playwrightスクリプトの作成
  2. 02エンドツーエンド・UIテストへの対応
  3. 03フォームと入力検証のテスト
  4. 04スクリーンショットとブラウザーログの取得
  5. 05セレクターと待機方法の案内

活用シーン

  1. 01ローカルWebアプリのユーザーフローのテスト
  2. 02フォーム送信と入力検証の確認
  3. 03視覚的な検証用スクリーンショットの取得
  4. 04ブラウザーエラーやテスト失敗の調査

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/curiositech/some_claude_skills --skill webapp-testing

インストール後、Claude Code で/webapp-testingを入力して読み込まれたか確認します。

同梱ファイル.claude-plugin/plugin.json

詳細

Web アプリケーションのテスト

ローカルの Web アプリケーションをテストするために、Python のネイティブな Playwright スクリプトを作成します。

使用する場面

✅ 次の用途に使用します:

  • Web アプリケーションの E2E テスト
  • UI の自動化とインタラクションテスト
  • ビジュアルリグレッションテスト
  • ブラウザーのログ取得とデバッグ
  • 検証用のスクリーンショット撮影
  • フォーム送信とバリデーションのテスト

❌ 次の用途には使用しません:

  • ブラウザーを使わない API のみのテスト(requests/httpx を使用)
  • 個々の関数のユニットテスト
  • モバイルアプリのテスト(Appium を使用)
  • 負荷/パフォーマンステスト(k6/Locust を使用)

判断ツリー:アプローチの選択

User task → Is it static HTML?
    ├─ Yes → Read HTML file directly to identify selectors
    │         ├─ Success → Write Playwright script using selectors
    │         └─ Fails/Incomplete → Treat as dynamic (below)
    │
    └─ No (dynamic webapp) → Is the server already running?
        ├─ No → Start server first, then run Playwright
        │
        └─ Yes → Reconnaissance-then-action:
            1. Navigate and wait for networkidle
            2. Take screenshot or inspect DOM
            3. Identify selectors from rendered state
            4. Execute actions with discovered selectors

Playwright の基本パターン

基本的なテスト構成
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)  # Always headless
    page = browser.new_page()
    page.goto('http://localhost:5173')
    page.wait_for_load_state('networkidle')  # CRITICAL for SPAs

    # ... your test logic

    browser.close()
偵察してから操作するパターン

手順 1:レンダリングされた DOM を調べる

page.screenshot(path='/tmp/inspect.png', full_page=True)
content = page.content()
buttons = page.locator('button').all()

手順 2:セレクターを特定する(調査結果に基づきます)

手順 3:操作を実行する(見つけたセレクターを使用します)

セレクター戦略(優先順位順)

  1. ロールベース(アクセシビリティに最適):

    page.get_by_role("button", name="Submit")
    page.get_by_role("textbox", name="Email")
    
  2. テキストベース(読みやすいものの、文言の変更に弱い):

    page.get_by_text("Sign In")
    page.get_by_label("Password")
    
  3. テスト ID(安定していて明示的):

    page.get_by_test_id("login-button")
    
  4. CSS セレクター(最後の手段):

    page.locator(".btn-primary")
    page.locator("#submit-form")
    

よくあるアンチパターン

アンチパターン:ネットワークがアイドル状態になるのを待たない

症状:ローカルではテストが成功するが CI では失敗する。要素が見つからない

問題:最新の SPA では、初回のページ読み込み後にコンテンツが動的に読み込まれます

解決策:

# ❌ Wrong
page.goto('http://localhost:3000')
page.click('button')  # Element may not exist yet

# ✅ Correct
page.goto('http://localhost:3000')
page.wait_for_load_state('networkidle')
page.click('button')
アンチパターン:待機時間のハードコード

症状:テスト内に time.sleep(3) が散在する

問題:処理が遅く、信頼性に欠け、実際のページ状態に応じて調整されません

解決策:

# ❌ Wrong
time.sleep(5)
page.click('.dynamic-button')

# ✅ Correct
page.wait_for_selector('.dynamic-button', state='visible')
page.click('.dynamic-button')
アンチパターン:JavaScript の実行前に DOM を調べる

症状:ページの内容が空で、静的解析では要素が見つからない

問題:クライアント側のレンダリングが完了する前に HTML を読み取っています

解決策:動的なアプリを調べる前に、必ず networkidle を待ちます

待機戦略

# Wait for element to appear
page.wait_for_selector('#my-element')

# Wait for element to be visible
page.wait_for_selector('#my-element', state='visible')

# Wait for element to be hidden
page.wait_for_selector('#my-element', state='hidden')

# Wait for navigation
page.wait_for_url('**/dashboard')

# Wait for network idle (all requests complete)
page.wait_for_load_state('networkidle')

# Custom wait with timeout
page.wait_for_function('document.querySelector(".loaded")')

スクリーンショットのパターン

# Full page screenshot
page.screenshot(path='/tmp/full.png', full_page=True)

# Element screenshot
page.locator('#header').screenshot(path='/tmp/header.png')

# Before/after comparison
page.screenshot(path='/tmp/before.png')
# ... perform action ...
page.screenshot(path='/tmp/after.png')

コンソールログの取得

# Capture all console messages
messages = []
page.on('console', lambda msg: messages.append({
    'type': msg.type,
    'text': msg.text
}))

# Filter errors only
page.on('console', lambda msg:
    print(f'ERROR: {msg.text}') if msg.type == 'error' else None
)

フォームのテスト

# Fill form fields
page.fill('#email', '[email protected]')
page.fill('#password', 'secret123')

# Select dropdown
page.select_option('#country', 'US')

# Check checkbox
page.check('#terms')

# Submit form
page.click('button[type="submit"]')

# Verify submission
page.wait_for_url('**/success')

アサーション

from playwright.sync_api import expect

# Element assertions
expect(page.locator('#title')).to_have_text('Welcome')
expect(page.locator('#count')).to_have_text('5')
expect(page.locator('.error')).to_be_hidden()
expect(page.locator('#submit')).to_be_enabled()

# Page assertions
expect(page).to_have_url('http://localhost:3000/dashboard')
expect(page).to_have_title('My App')

複数ページのシナリオ

# Handle popup windows
with page.expect_popup() as popup_info:
    page.click('#open-popup')
popup = popup_info.value
popup.wait_for_load_state()

# Handle new tabs
with context.expect_page() as new_page_info:
    page.click('a[target="_blank"]')
new_page = new_page_info.value

テストファイルの構成

tests/
├── conftest.py          # Shared fixtures
├── test_login.py        # Login flows
├── test_dashboard.py    # Dashboard features
├── test_forms.py        # Form submissions
└── screenshots/         # Visual artifacts

テストの実行

# Run single test file
python -m pytest tests/test_login.py

# Run with browser visible (debugging)
PWDEBUG=1 python -m pytest tests/test_login.py

# Generate trace for debugging
python -m pytest --tracing=on tests/test_login.py

ベストプラクティス

  1. 同期スクリプトでは sync_playwright() を使用します
  2. 完了したら必ずブラウザーを閉じます
  3. わかりやすいセレクターを使用します:CSS よりもロール、テキスト、テスト ID を優先します
  4. 適切な待機処理を追加します:wait_for_selector()、wait_for_load_state()
  5. デバッグ用に失敗時のスクリーンショットを撮影します
  6. テストを独立させます。各テストで独自の状態をセットアップしてください

このスキルに含まれる内容:Playwright のベストプラクティス | セレクター戦略 | 待機パターン | アンチパターンの防止 | E2E テストのワークフロー

コメント