mcpField
W
webapp-testing

webapp-testing

github.com/oimiragieoテスト・品質4444 回インストール17 週間前に更新
リポジトリ

webapp-testing について

webapp-testingは、PlaywrightのPython APIでローカルWebアプリをテストするスキルです。静的ファイルと稼働中のアプリ向けの手順を備え、操作確認、スクリーンショット、コンソールエラーの確認を行えます。

主な機能

  1. 01Playwright PythonによるローカルWebアプリのテスト
  2. 02静的・動的アプリに応じた方法の選択
  3. 03フロントエンドの動作と操作の確認
  4. 04スクリーンショット取得とコンソールエラー確認
  5. 05自動テストスクリプトの生成

活用シーン

  1. 01フォームやナビゲーションフローの確認
  2. 02UIの表示や動作のデバッグ
  3. 03ビジュアル回帰用のスクリーンショット取得
  4. 04ブラウザーコンソールのJavaScriptエラー検出

MCP 対応

このスキルでは、Puppeteer MCPサーバーを使う任意のブラウザー自動化も説明しています。ナビゲーション、スクリーンショット、クリック、フォーム入力、選択、ホバー、ページ評価のツールを紹介します。

インストール

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

$npx skills add https://github.com/oimiragieo/agent-studio --skill webapp-testing

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

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

commands/
webapp-testing.md
hooks/
post-execute.cjs
pre-execute.cjs
references/
research-requirements.md
rules/
webapp-testing.md
schemas/
input.schema.json
output.schema.json
scripts/
main.cjs
templates/
implementation-template.md

詳細

Web Application Testing Skill

Anthropic の公式スキルリポジトリを基にした、Web アプリケーションテストツールキットです。Python で Playwright を使用してローカルの Web アプリケーションをテストするための体系的な手法を提供します。フロントエンドの検証、UI のデバッグ、スクリーンショットの撮影、ブラウザーのコンソールログ分析を網羅しています。 - Playwright(Python)によるローカル Web アプリケーションのテスト - フロントエンド機能の検証 - UI の動作のデバッグと調査 - 重要な操作時点でのブラウザーのスクリーンショット撮影 - ブラウザーのコンソールログの表示とエラー検出 - 静的 HTML ファイルのテスト(直接読み取り+セレクターの特定) - サーバーのライフサイクル管理を伴う動的 Web アプリのテスト - 自動テストスクリプトの生成 - 要素の検出と CSS セレクターの特定 - ページ読み込み状態の管理(networkidle、domcontentloaded、load)

概要

このスキルは、agent-studio フレームワーク向けに Anthropic の webapp-testing スキルを応用したものです。テスト対象の Web コンテンツの種類に応じて適切な戦略を選び、Playwright を使ってローカルの Web アプリケーションをテストするための体系的なアプローチを提供します。

ソースリポジトリ:https://github.com/anthropics/skills ライセンス:MIT ツール:Playwright(Python API)

使用する場面

  • Web アプリケーションのフロントエンド機能を検証するとき
  • UI の動作や視覚的なレンダリングの問題をデバッグするとき
  • ビジュアルリグレッションテスト用のスクリーンショットを撮影するとき
  • ブラウザーのコンソールで JavaScript エラーを確認するとき
  • フォーム送信、ナビゲーションフロー、インタラクティブ要素をテストするとき
  • Web アプリケーション用の自動テストスクリプトを生成するとき

鉄則

NEVER INSPECT DOM BEFORE WAITING FOR NETWORKIDLE ON DYNAMIC APPS

動的な Web アプリケーションは、コンテンツを非同期に読み込みます。ページが安定する前に DOM を調べると、不正確または不完全な結果になります。動的アプリでは、レンダリングされたコンテンツを調べる前に必ず page.wait_for_load_state('networkidle') を呼び出してください。

判断フロー:アプローチの選択

Is the target a static HTML file?
  YES → Approach A: Direct Read
  NO → Is there a running dev server?
    YES → Approach B: Reconnaissance-then-Action
    NO → Approach C: Helper Script First
アプローチ A:静的 HTML ファイル

サーバーを必要としない静的 HTML ファイルの場合:

  1. HTML ファイルを直接読み取ります
  2. 対象の要素に対応する CSS セレクターを特定します
  3. ファイルを開いてコンテンツを検証する Playwright スクリプトを作成します
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    page = browser.new_page()
    page.goto(f"file://{abs_path_to_html}")

    # Verify content
    title = page.title()
    assert title == "Expected Title"

    # Check element exists
    element = page.query_selector("h1.main-heading")
    assert element is not None

    # Capture screenshot
    page.screenshot(path="screenshot.png")
    browser.close()
アプローチ B:サーバー実行中(調査してから操作)

開発サーバーがすでに実行中の場合:

  1. 調査:アプリに移動し、ページ構造を確認します
  2. 安定するまで待機:page.wait_for_load_state('networkidle')
  3. 確認:要素を検索し、コンテンツを読み取り、コンソールログを確認します
  4. 操作:フォーム、ボタン、ナビゲーションを操作します
  5. 検証:期待される結果をアサートします
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    page = browser.new_page()

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

    # Navigate and wait for stability
    page.goto("http://localhost:3000")
    page.wait_for_load_state("networkidle")

    # Discover page structure
    headings = page.query_selector_all("h1, h2, h3")
    buttons = page.query_selector_all("button")
    forms = page.query_selector_all("form")
    links = page.query_selector_all("a[href]")

    # Print discovered elements
    for h in headings:
        print(f"Heading: {h.text_content()}")
    for btn in buttons:
        print(f"Button: {btn.text_content()}")

    # Screenshot before interaction
    page.screenshot(path="before-interaction.png")

    # Interact with form
    page.fill("input[name='email']", "[email protected]")
    page.fill("input[name='password']", "testpass123")
    page.click("button[type='submit']")
    page.wait_for_load_state("networkidle")

    # Screenshot after interaction
    page.screenshot(path="after-interaction.png")

    # Check for console errors
    errors = [m for m in console_messages if "[error]" in m.lower()]
    if errors:
        print(f"Console errors found: {errors}")

    browser.close()
アプローチ C:サーバー未実行(ヘルパースクリプト)

Web アプリのサーバーを起動する必要がある場合:

import subprocess
import time
from playwright.sync_api import sync_playwright

# Start the server
server_proc = subprocess.Popen(
    ["npm", "run", "dev"],
    cwd="/path/to/project",
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE,
    shell=False  # Security: always shell=False
)

# Wait for server to be ready
time.sleep(5)  # Or use a health check loop

try:
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=True)
        page = browser.new_page()
        page.goto("http://localhost:3000")
        page.wait_for_load_state("networkidle")

        # Run tests...
        page.screenshot(path="test-result.png")
        browser.close()
finally:
    server_proc.terminate()
    server_proc.wait()

よく使われるテストパターン

パターン 1:ビジュアルリグレッションチェック
# Take baseline screenshot
page.screenshot(path="baseline.png", full_page=True)

# After changes, take comparison screenshot
page.screenshot(path="current.png", full_page=True)

# Compare (use image diff library)
パターン 2:フォーム検証テスト
# Test empty submission
page.click("button[type='submit']")
error_msgs = page.query_selector_all(".error-message")
assert len(error_msgs) > 0, "Expected validation errors for empty form"

# Test invalid email
page.fill("input[type='email']", "not-an-email")
page.click("button[type='submit']")
email_error = page.query_selector("input[type='email']:invalid")
assert email_error is not None
パターン 3:ナビゲーションフローテスト
# Test navigation links
nav_links = page.query_selector_all("nav a")
for link in nav_links:
    href = link.get_attribute("href")
    link.click()
    page.wait_for_load_state("networkidle")
    assert page.url.endswith(href), f"Expected URL to end with {href}"
    page.go_back()
    page.wait_for_load_state("networkidle")
パターン 4:レスポンシブデザインテスト
viewports = [
    {"width": 375, "height": 812, "name": "mobile"},
    {"width": 768, "height": 1024, "name": "tablet"},
    {"width": 1920, "height": 1080, "name": "desktop"},
]

for vp in viewports:
    page.set_viewport_size({"width": vp["width"], "height": vp["height"]})
    page.wait_for_load_state("networkidle")
    page.screenshot(path=f"responsive-{vp['name']}.png")

重大な注意点

  1. networkidle の前に DOM を調べないでください:動的アプリはコンテンツを非同期に読み込みます。早すぎる確認では結果が不完全になります。
  2. shell=True を使用しないでください:サーバープロセスを起動するときは、安全のため常に配列形式の引数を使って shell=False を指定してください。
  3. 固定時間の待機を使用しないでください:time.sleep() の代わりに page.wait_for_selector() または page.wait_for_load_state() を使用してください。
  4. コンソールエラーを無視しないでください:ブラウザーのコンソールエラーは必ず取得して報告してください。実際の問題を示しています。
  5. クリーンアップを忘れないでください:必ず finally ブロックでサーバープロセスを終了してください。

前提条件

Playwright がインストールされていることを確認してください。

pip install playwright
playwright install chromium

Agent-Studio との連携

推奨ワークフロー
  1. webapp-testing を使ってフロントエンドの動作を検証します
  2. スクリーンショットの証拠を code-reviewer に渡して、視覚的なレビューを行います
  3. tdd スキルを使って、発見したパターンからテストスイートを生成します
  4. accessibility スキルを使って、WCAG への準拠を検証します
補完スキル
スキル関連性
tddwebapp-testing での発見事項からテストスイートを生成します
accessibility機能テスト後に WCAG 準拠を検証します
frontend-expertテスト設計のための UI/UX パターンの指針
chrome-browser代替となるブラウザー自動化アプローチ
test-generatorテストパターンからテストコードを生成します

絶対に守るべき原則

  1. NETWORKIDLE の前に DOM を決して調査しないでください — 動的なウェブアプリケーションはコンテンツを非同期で読み込みます。ページが安定する前に DOM を調査すると、誤った結果や不完全な結果が生じます。
  2. サーバープロセスの起動に shell=True を決して使用しないでください — 常に配列引数を指定して shell=False を使用してください(SE-01 のセキュリティ要件)。
  3. 常にコンソールエラーを記録してください — ブラウザーのコンソールエラーは実際の問題を示しています。テストレポートで決して無視しないでください。
  4. 常に finally ブロックでサーバープロセスを終了してください — サーバープロセスが残ると、後続のテスト実行に支障をきたし、リソースを消費します。
  5. 固定時間の待機は決して使用しないでください — time.sleep() の代わりに page.wait_for_selector() または page.wait_for_load_state() を使用してください。

アンチパターン

アンチパターン失敗する理由正しい方法
networkidle の前に DOM を調査する動的コンテンツがまだ読み込まれておらず、アサーションで誤検知が発生します調査の前に必ず page.wait_for_load_state('networkidle') を実行します
待機に time.sleep() を使用する不安定です。低速なマシンでは短すぎ、高速なマシンでは長すぎます明示的な待機を使用します:wait_for_selector、wait_for_load_state
ブラウザーのコンソールエラーを無視する実際の JS エラーが検出されず、アプリが壊れていてもテストに合格しますテスト実行ごとに必ずコンソールエラーを記録して報告します
サーバープロセスに shell=True を使用するコマンドインジェクションの脆弱性リスト引数を指定して常に shell=False を使用します
サーバープロセスをクリーンアップしない後続の実行でポート競合やリソースリークが発生しますtry/finally を使用して server_proc.terminate() の実行を保証します

Puppeteer MCP ブラウザー自動化

Python を使わずにエージェントネイティブなブラウザー自動化を行うには、modelcontextprotocol/servers の Puppeteer MCP サーバーを使用します。

セットアップ

mcpServers の下に .claude/settings.json を追加します。

"puppeteer": {
  "command": "npx",
  "args": ["-y", "@modelcontextprotocol/server-puppeteer"]
}
MCP ツールリファレンス
ツール用途
puppeteer_navigateURL に移動して、ページの読み込みを待機します
puppeteer_screenshotスクリーンショットを撮影します(全ページまたは要素)
puppeteer_clickCSS セレクターをクリックします
puppeteer_fillフォーム入力に値を入力します
puppeteer_select値でドロップダウンのオプションを選択します
puppeteer_hover要素にマウスカーソルを合わせます
puppeteer_evaluateブラウザーコンテキストで JavaScript を実行します
使用パターン
// Navigate and capture state
mcp__puppeteer__puppeteer_navigate({ url: 'http://localhost:3000' });
mcp__puppeteer__puppeteer_screenshot({ name: 'initial-state', fullPage: true });

// Interact with forms
mcp__puppeteer__puppeteer_fill({ selector: 'input[name="email"]', value: '[email protected]' });
mcp__puppeteer__puppeteer_click({ selector: 'button[type="submit"]' });
mcp__puppeteer__puppeteer_screenshot({ name: 'after-submit' });

// Evaluate page state
mcp__puppeteer__puppeteer_evaluate({
  script:
    'JSON.stringify({ title: document.title, errors: [...document.querySelectorAll(".error")].map(e => e.textContent) })',
});
Puppeteer MCP と Playwright Python の使い分け
シナリオ使用するもの
エージェントのワークフロー内で手早くページを確認するPuppeteer MCP
アサーションを含む複雑なテストスイートPlaywright Python
証拠としてスクリーンショットを取得するPuppeteer MCP
フォーム操作とナビゲーションどちらでも可
CI テストの自動化Playwright Python
エージェントに組み込まれたブラウザチェックPuppeteer MCP

メモリプロトコル(必須)

開始前:

.claude/context/memory/learnings.md を読みます。

次の項目を確認します:

  • プロジェクト内の既存のテストスクリプトまたは Playwright の設定
  • 過去のセッションで判明したページセレクター
  • 以前に発見されたコンソールエラーまたは不安定なテストパターン

完了後:

  • 発見したテストパターン -> .claude/context/memory/learnings.md
  • テストの不安定さまたはブラウザーの問題 -> .claude/context/memory/issues.md
  • テスト戦略に関する決定 -> .claude/context/memory/decisions.md

中断されることを前提にしてください。メモリに記録されていないことは、起きていないものとして扱います。

コメント