From 9bef967b3c5ba12b36511d2af9cd36ea6fee9511 Mon Sep 17 00:00:00 2001 From: "takemi.ohama" Date: Sat, 8 Aug 2026 02:52:49 +0000 Subject: [PATCH 1/2] =?UTF-8?q?chore:=20feature/inventory-merge-playwright?= =?UTF-8?q?=20=E3=81=AE=20Draft=20PR=20=E4=BD=9C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From 229338348f5e75adbc8240bfe47847727e7dd646 Mon Sep 17 00:00:00 2001 From: "takemi.ohama" Date: Sat, 8 Aug 2026 03:10:16 +0000 Subject: [PATCH 2/2] =?UTF-8?q?Refactor:=20=E3=83=96=E3=83=A9=E3=82=A6?= =?UTF-8?q?=E3=82=B6=E8=87=AA=E5=8B=95=E3=83=86=E3=82=B9=E3=83=88=20Skill?= =?UTF-8?q?=209=20=E5=80=8B=E3=82=92=E5=B7=A5=E7=A8=8B=E5=8D=98=E4=BD=8D?= =?UTF-8?q?=E3=81=AE=204=20=E5=80=8B=E3=81=B8=E7=B5=B1=E5=90=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task 0-5。ブラウザ自動テスト関連の 9 Skill を工程単位で 4 個に集約する。 - playwright-planning ← playwright-test-planning + playwright-scenario-test - playwright-authoring ← playwright-script-creation + playwright-execution + browser-test + playwright-browser-connect - playwright-evidence ← playwright-report + playwright-evidence-drive - playwright-kit-ops は実行環境ディレクトリを持つため単独で維持 単純連結ではなく重複記述を落として再構成し、SKILL.md 合計は 1,381 行から 662 行へ削減した。playwright-browser-connect の CDP 接続手順は playwright-authoring/references/browser-connection.md へ分割し、 全 SKILL.md を 500 行以内に収めた。 manifest は claude / kiro の browser-test を playwright-authoring に置換し、 codex の playwright 系 5 個を統合後の 4 個へ置換した。 旧 Skill 名への参照 (README / plugin.json / issue-plan-strategy / playwright_kit の docstring とテンプレート) をすべて更新した。 Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01AGejnYyYFuSkQjBhW2KQNy --- README.md | 10 +- plugins/ndf-claude/.claude-plugin/plugin.json | 2 +- .../ndf-claude/skills/browser-test/SKILL.md | 159 --------- .../skills/issue-plan-strategy/SKILL.md | 4 +- .../skills/playwright-authoring/SKILL.md | 250 ++++++++++++++ .../references/browser-connection.md} | 262 +++----------- .../scripts/start-host-chrome.sh | 0 .../skills/issue-plan-strategy/SKILL.md | 4 +- .../skills/playwright-authoring/SKILL.md | 250 ++++++++++++++ .../references/browser-connection.md | 326 ++++++++++++++++++ .../scripts/start-host-chrome.sh | 172 +++++++++ .../skills/playwright-evidence/SKILL.md | 172 +++++++++ .../skills/playwright-execution/SKILL.md | 101 ------ .../skills/playwright-kit-ops/SKILL.md | 9 +- .../playwright_kit/fixtures/__init__.py | 2 +- .../playwright_kit/pytest_plugin.py | 4 +- .../templates/conftest.py.template | 4 +- .../templates/scenario.config.yaml | 2 +- .../skills/playwright-planning/SKILL.md | 124 +++++++ .../docs/01-methodology.md | 0 .../docs/02-page-roles.md | 0 .../docs/03-test-techniques.md | 0 .../docs/04-playwright-mapping.md | 0 .../docs/05-bug-report.md | 0 .../docs/06-pytest-playwright.md | 0 .../docs/README.md | 0 .../docs/checklists/checklist-auth.md | 0 .../checklists/checklist-cart-checkout.md | 0 .../docs/checklists/checklist-common.md | 0 .../docs/checklists/checklist-dashboard.md | 0 .../docs/checklists/checklist-edit.md | 0 .../docs/checklists/checklist-form.md | 0 .../docs/checklists/checklist-item.md | 0 .../docs/checklists/checklist-list.md | 0 .../docs/checklists/checklist-lp.md | 0 .../docs/checklists/checklist-modal-wizard.md | 0 .../docs/checklists/checklist-search.md | 0 .../skills/playwright-report/SKILL.md | 55 --- .../playwright-script-creation/SKILL.md | 108 ------ .../skills/playwright-test-planning/SKILL.md | 97 ------ plugins/ndf-kiro/skills/browser-test/SKILL.md | 159 --------- .../skills/issue-plan-strategy/SKILL.md | 4 +- .../skills/playwright-authoring/SKILL.md | 250 ++++++++++++++ .../references/browser-connection.md | 326 ++++++++++++++++++ .../scripts/start-host-chrome.sh | 172 +++++++++ .../ndf-shared/manifests/claude-skills.txt | 2 +- plugins/ndf-shared/manifests/codex-skills.txt | 7 +- plugins/ndf-shared/manifests/kiro-skills.txt | 2 +- .../ndf-shared/skills/browser-test/SKILL.md | 159 --------- .../skills/issue-plan-strategy/SKILL.md | 4 +- .../skills/playwright-authoring/SKILL.md | 250 ++++++++++++++ .../references/browser-connection.md | 326 ++++++++++++++++++ .../scripts/start-host-chrome.sh | 172 +++++++++ .../skills/playwright-evidence-drive/SKILL.md | 190 ---------- .../skills/playwright-evidence/SKILL.md | 172 +++++++++ .../skills/playwright-execution/SKILL.md | 101 ------ .../skills/playwright-kit-ops/SKILL.md | 9 +- .../playwright_kit/fixtures/__init__.py | 2 +- .../playwright_kit/pytest_plugin.py | 4 +- .../templates/conftest.py.template | 4 +- .../templates/scenario.config.yaml | 2 +- .../skills/playwright-planning/SKILL.md | 124 +++++++ .../docs/01-methodology.md | 0 .../docs/02-page-roles.md | 0 .../docs/03-test-techniques.md | 0 .../docs/04-playwright-mapping.md | 0 .../docs/05-bug-report.md | 0 .../docs/06-pytest-playwright.md | 0 .../docs/README.md | 0 .../docs/checklists/checklist-auth.md | 0 .../checklists/checklist-cart-checkout.md | 0 .../docs/checklists/checklist-common.md | 0 .../docs/checklists/checklist-dashboard.md | 0 .../docs/checklists/checklist-edit.md | 0 .../docs/checklists/checklist-form.md | 0 .../docs/checklists/checklist-item.md | 0 .../docs/checklists/checklist-list.md | 0 .../docs/checklists/checklist-lp.md | 0 .../docs/checklists/checklist-modal-wizard.md | 0 .../docs/checklists/checklist-search.md | 0 .../skills/playwright-report/SKILL.md | 55 --- .../skills/playwright-scenario-test/SKILL.md | 68 ---- .../playwright-script-creation/SKILL.md | 108 ------ .../skills/playwright-test-planning/SKILL.md | 97 ------ 84 files changed, 3175 insertions(+), 1711 deletions(-) delete mode 100644 plugins/ndf-claude/skills/browser-test/SKILL.md create mode 100644 plugins/ndf-claude/skills/playwright-authoring/SKILL.md rename plugins/{ndf-shared/skills/playwright-browser-connect/SKILL.md => ndf-claude/skills/playwright-authoring/references/browser-connection.md} (50%) rename plugins/{ndf-shared/skills/playwright-browser-connect => ndf-claude/skills/playwright-authoring}/scripts/start-host-chrome.sh (100%) create mode 100644 plugins/ndf-codex/skills/playwright-authoring/SKILL.md create mode 100644 plugins/ndf-codex/skills/playwright-authoring/references/browser-connection.md create mode 100755 plugins/ndf-codex/skills/playwright-authoring/scripts/start-host-chrome.sh create mode 100644 plugins/ndf-codex/skills/playwright-evidence/SKILL.md delete mode 100644 plugins/ndf-codex/skills/playwright-execution/SKILL.md create mode 100644 plugins/ndf-codex/skills/playwright-planning/SKILL.md rename plugins/ndf-codex/skills/{playwright-test-planning => playwright-planning}/docs/01-methodology.md (100%) rename plugins/ndf-codex/skills/{playwright-test-planning => playwright-planning}/docs/02-page-roles.md (100%) rename plugins/ndf-codex/skills/{playwright-test-planning => playwright-planning}/docs/03-test-techniques.md (100%) rename plugins/ndf-codex/skills/{playwright-test-planning => playwright-planning}/docs/04-playwright-mapping.md (100%) rename plugins/ndf-codex/skills/{playwright-test-planning => playwright-planning}/docs/05-bug-report.md (100%) rename plugins/ndf-codex/skills/{playwright-test-planning => playwright-planning}/docs/06-pytest-playwright.md (100%) rename plugins/ndf-codex/skills/{playwright-test-planning => playwright-planning}/docs/README.md (100%) rename plugins/ndf-codex/skills/{playwright-test-planning => playwright-planning}/docs/checklists/checklist-auth.md (100%) rename plugins/ndf-codex/skills/{playwright-test-planning => playwright-planning}/docs/checklists/checklist-cart-checkout.md (100%) rename plugins/ndf-codex/skills/{playwright-test-planning => playwright-planning}/docs/checklists/checklist-common.md (100%) rename plugins/ndf-codex/skills/{playwright-test-planning => playwright-planning}/docs/checklists/checklist-dashboard.md (100%) rename plugins/ndf-codex/skills/{playwright-test-planning => playwright-planning}/docs/checklists/checklist-edit.md (100%) rename plugins/ndf-codex/skills/{playwright-test-planning => playwright-planning}/docs/checklists/checklist-form.md (100%) rename plugins/ndf-codex/skills/{playwright-test-planning => playwright-planning}/docs/checklists/checklist-item.md (100%) rename plugins/ndf-codex/skills/{playwright-test-planning => playwright-planning}/docs/checklists/checklist-list.md (100%) rename plugins/ndf-codex/skills/{playwright-test-planning => playwright-planning}/docs/checklists/checklist-lp.md (100%) rename plugins/ndf-codex/skills/{playwright-test-planning => playwright-planning}/docs/checklists/checklist-modal-wizard.md (100%) rename plugins/ndf-codex/skills/{playwright-test-planning => playwright-planning}/docs/checklists/checklist-search.md (100%) delete mode 100644 plugins/ndf-codex/skills/playwright-report/SKILL.md delete mode 100644 plugins/ndf-codex/skills/playwright-script-creation/SKILL.md delete mode 100644 plugins/ndf-codex/skills/playwright-test-planning/SKILL.md delete mode 100644 plugins/ndf-kiro/skills/browser-test/SKILL.md create mode 100644 plugins/ndf-kiro/skills/playwright-authoring/SKILL.md create mode 100644 plugins/ndf-kiro/skills/playwright-authoring/references/browser-connection.md create mode 100755 plugins/ndf-kiro/skills/playwright-authoring/scripts/start-host-chrome.sh delete mode 100644 plugins/ndf-shared/skills/browser-test/SKILL.md create mode 100644 plugins/ndf-shared/skills/playwright-authoring/SKILL.md create mode 100644 plugins/ndf-shared/skills/playwright-authoring/references/browser-connection.md create mode 100755 plugins/ndf-shared/skills/playwright-authoring/scripts/start-host-chrome.sh delete mode 100644 plugins/ndf-shared/skills/playwright-evidence-drive/SKILL.md create mode 100644 plugins/ndf-shared/skills/playwright-evidence/SKILL.md delete mode 100644 plugins/ndf-shared/skills/playwright-execution/SKILL.md create mode 100644 plugins/ndf-shared/skills/playwright-planning/SKILL.md rename plugins/ndf-shared/skills/{playwright-test-planning => playwright-planning}/docs/01-methodology.md (100%) rename plugins/ndf-shared/skills/{playwright-test-planning => playwright-planning}/docs/02-page-roles.md (100%) rename plugins/ndf-shared/skills/{playwright-test-planning => playwright-planning}/docs/03-test-techniques.md (100%) rename plugins/ndf-shared/skills/{playwright-test-planning => playwright-planning}/docs/04-playwright-mapping.md (100%) rename plugins/ndf-shared/skills/{playwright-test-planning => playwright-planning}/docs/05-bug-report.md (100%) rename plugins/ndf-shared/skills/{playwright-test-planning => playwright-planning}/docs/06-pytest-playwright.md (100%) rename plugins/ndf-shared/skills/{playwright-test-planning => playwright-planning}/docs/README.md (100%) rename plugins/ndf-shared/skills/{playwright-test-planning => playwright-planning}/docs/checklists/checklist-auth.md (100%) rename plugins/ndf-shared/skills/{playwright-test-planning => playwright-planning}/docs/checklists/checklist-cart-checkout.md (100%) rename plugins/ndf-shared/skills/{playwright-test-planning => playwright-planning}/docs/checklists/checklist-common.md (100%) rename plugins/ndf-shared/skills/{playwright-test-planning => playwright-planning}/docs/checklists/checklist-dashboard.md (100%) rename plugins/ndf-shared/skills/{playwright-test-planning => playwright-planning}/docs/checklists/checklist-edit.md (100%) rename plugins/ndf-shared/skills/{playwright-test-planning => playwright-planning}/docs/checklists/checklist-form.md (100%) rename plugins/ndf-shared/skills/{playwright-test-planning => playwright-planning}/docs/checklists/checklist-item.md (100%) rename plugins/ndf-shared/skills/{playwright-test-planning => playwright-planning}/docs/checklists/checklist-list.md (100%) rename plugins/ndf-shared/skills/{playwright-test-planning => playwright-planning}/docs/checklists/checklist-lp.md (100%) rename plugins/ndf-shared/skills/{playwright-test-planning => playwright-planning}/docs/checklists/checklist-modal-wizard.md (100%) rename plugins/ndf-shared/skills/{playwright-test-planning => playwright-planning}/docs/checklists/checklist-search.md (100%) delete mode 100644 plugins/ndf-shared/skills/playwright-report/SKILL.md delete mode 100644 plugins/ndf-shared/skills/playwright-scenario-test/SKILL.md delete mode 100644 plugins/ndf-shared/skills/playwright-script-creation/SKILL.md delete mode 100644 plugins/ndf-shared/skills/playwright-test-planning/SKILL.md diff --git a/README.md b/README.md index 97a6176d..ce014a94 100644 --- a/README.md +++ b/README.md @@ -8,15 +8,15 @@ Claude Code / Codex / Kiro CLI向けのスキル・MCP設定を共有するた **NDFプラグイン v4.20.1** は、同じ `ndf@ai-plugins` という名前で Claude Code / Codex / Kiro CLI へ配布されるランタイム別プラグインです。共通ソースは `plugins/ndf-shared/` に集約し、利用者が install する配布物は `plugins/ndf-claude/` / `plugins/ndf-codex/` / `plugins/ndf-kiro/` に分かれています。 -- **公開Skills**: Claude Code向け core 29個、Kiro向け core 28個、Codex向け core 30個に分離。 -- **元Skills(49個)**: - - PR/レビューワークフロー (13): pr, pr-tests, fix, review, review-branch, review-pr-comments, resolve-pr-comments, cherry-pick-pr, deploy, sync-main, merged, clean, browser-test +- **公開Skills**: Claude Code向け core 29個、Kiro向け core 28個、Codex向け core 29個に分離。 +- **元Skills(44個)**: + - PR/レビューワークフロー (12): pr, pr-tests, fix, review, review-branch, review-pr-comments, resolve-pr-comments, cherry-pick-pr, deploy, sync-main, merged, clean - 原則・ガイドライン (10): ndf-policies, branch-fix-strategy, implementation-plan, plan-to-spec, investigation-rules, problem-solving, logging-guidelines, markdown-writing, issue-plan-strategy, ml-model-structure - データ分析・品質・環境 (12): data-analyst-sql-optimization, data-analyst-export, qa-security-scan, python-execution, docker-container-access, git-gh-operations, google-auth, codex, deepwiki-transfer, knowledge-reorg, mcp-builder, official-skills-autoloader - - E2Eテスト/Playwright (6): playwright-test-planning, playwright-script-creation, playwright-execution, playwright-report, playwright-kit-ops, playwright-scenario-test + - E2Eテスト/Playwright (4): playwright-planning, playwright-authoring, playwright-evidence, playwright-kit-ops - 外部サービス連携 (2): google-drive, google-chat - AIクロスレビュー (2): cross-review, gemini - - 運用 (1): skill-stats + - 運用 (2): skill-stats, statusline - **8つの専門エージェント**: director, data-analyst, corder, researcher, qa, debugger, devops-engineer, code-reviewer - **自動フック**: SessionStart (transcript保持期間を最低90日に保つ) + Stop (AI要約生成+Slack通知) - **外部AI委譲**: `/ndf:codex` skill + `corder` エージェント経由で Codex CLI をバックグラウンド実行 (v4.0.0 で Codex MCP サーバは廃止) diff --git a/plugins/ndf-claude/.claude-plugin/plugin.json b/plugins/ndf-claude/.claude-plugin/plugin.json index 1dfb737a..01076394 100644 --- a/plugins/ndf-claude/.claude-plugin/plugin.json +++ b/plugins/ndf-claude/.claude-plugin/plugin.json @@ -51,7 +51,7 @@ "./skills/review-branch", "./skills/review-pr-comments", "./skills/resolve-pr-comments", - "./skills/browser-test", + "./skills/playwright-authoring", "./skills/codex", "./skills/gemini", "./skills/statusline", diff --git a/plugins/ndf-claude/skills/browser-test/SKILL.md b/plugins/ndf-claude/skills/browser-test/SKILL.md deleted file mode 100644 index 97eb0c82..00000000 --- a/plugins/ndf-claude/skills/browser-test/SKILL.md +++ /dev/null @@ -1,159 +0,0 @@ ---- -name: browser-test -description: "Run browser smoke tests for web apps." -argument-hint: "[url]" -disable-model-invocation: true -allowed-tools: - - Bash - - mcp__playwright__browser_navigate - - mcp__playwright__browser_snapshot - - mcp__playwright__browser_click - - mcp__playwright__browser_fill_form - - mcp__playwright__browser_take_screenshot - - mcp__playwright__browser_type - - mcp__playwright__browser_evaluate - - mcp__playwright__browser_console_messages - - mcp__playwright__browser_wait_for - - mcp__playwright__browser_tabs - - mcp__playwright__browser_navigate_back - - mcp__playwright__browser_close - - mcp__playwright__browser_resize - - mcp__playwright__browser_handle_dialog - - mcp__playwright__browser_press_key - - mcp__playwright__browser_hover - - mcp__playwright__browser_select_option - - mcp__playwright__browser_drag - - mcp__playwright__browser_network_requests - - mcp__playwright__browser_file_upload - - mcp__playwright__browser_install - - mcp__chrome-devtools__navigate_page - - mcp__chrome-devtools__take_snapshot - - mcp__chrome-devtools__click - - mcp__chrome-devtools__fill_form - - mcp__chrome-devtools__take_screenshot - - mcp__chrome-devtools__type - - mcp__chrome-devtools__evaluate_script - - mcp__chrome-devtools__list_console_messages - - mcp__chrome-devtools__wait_for - - mcp__chrome-devtools__list_pages - - mcp__chrome-devtools__new_page - - mcp__chrome-devtools__select_page - - mcp__chrome-devtools__close_page - - mcp__chrome-devtools__navigate_page_history - - mcp__chrome-devtools__resize_page - - mcp__chrome-devtools__handle_dialog - - mcp__chrome-devtools__hover - - mcp__chrome-devtools__drag - - mcp__chrome-devtools__list_network_requests - - mcp__chrome-devtools__get_network_request - - mcp__chrome-devtools__upload_file - - mcp__chrome-devtools__emulate_network - - mcp__chrome-devtools__emulate_cpu - - mcp__chrome-devtools__performance_start_trace - - mcp__chrome-devtools__performance_stop_trace - - mcp__chrome-devtools__performance_analyze_insight ---- - -# ブラウザ動作確認コマンド - -現在のブランチで実装されたWeb機能をブラウザで動作確認する。Playwright MCP または Chrome DevTools MCP を利用可能な方を自動選択する。 - -## 前提条件(重要) - -このコマンドは以下のいずれかのMCPサーバが必要: - -- **Playwright MCP**: 自動的にブラウザを起動(要Playwrightインストール) -- **Chrome DevTools MCP**: 既に開いているChromeを操作(Chromeをデバッグモードで起動しておく必要あり) - -どちらも利用できない環境では、手動確認手順を案内する。 - -## 使用方法 - -``` -/ndf:browser-test # 現在のブランチの実装を確認 -/ndf:browser-test http://localhost:8080 # 特定URLを確認 -``` - -## MCPの使い分け - -### Playwright MCP -- 自動的にブラウザを起動 -- 複数ブラウザ対応 (Chromium/Firefox/WebKit) -- 利用可能なら第一選択 - -### Chrome DevTools MCP -- 既に開いているChromeブラウザを操作 -- Chrome デバッグモードでの起動が必要: - - macOS: `/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222` - - Windows: `chrome.exe --remote-debugging-port=9222` - - Linux: `google-chrome --remote-debugging-port=9222` -- DevTools統合でパフォーマンス分析可能 - -## 処理フロー - -### 1. アプリケーション起動確認 - -プロジェクトで使っている起動方法に応じて確認: - -```bash -# Docker Compose の場合 -docker compose ps - -# ネイティブ起動の場合 -curl -fsS http://localhost:/health || echo "NOT RUNNING" -``` - -起動していない場合は、起動手順をユーザーに案内。 - -### 2. ブラウザアクセスと認証 - -- 指定URL(または `/` )にアクセス -- 必要に応じてログイン(資格情報はプロジェクト固有、事前に取得しておく) - -### 3. 機能画面への遷移 - -実装された機能に応じて適切な画面に遷移する。 - -### 4. 動作確認 - -必要に応じて以下の操作を実行: - -- フォーム入力 -- ボタンクリック -- データ表示の確認 -- コンソールエラーの確認 -- ネットワークリクエストの確認 -- スクリーンショット(明示的に指示された場合のみ) - -### 5. 結果報告 - -```markdown -## 動作確認結果 - -### 実施項目 -- [x] ログイン -- [x] 機能画面表示 -- [x] フォーム送信 -- [x] 結果表示 - -### 確認事項 -- コンソールエラー: なし -- ネットワークエラー: なし -- 期待結果との一致: ok - -### 気になる点 -- ...(あれば) -``` - -## 注意事項 - -- **事前にアプリケーション起動が必要** -- **ログイン情報**: プロジェクトの `.env.example` / README 等から確認。機密情報として扱う -- **スクリーンショット**: 必要な場合のみ明示的に指示されたときに取得 -- **Chrome DevTools使用時**: Chromeをデバッグモードで起動しておく必要あり -- **MCP未インストール環境**: 手動での確認手順を案内する - -## 関連 - -- `/ndf:review-branch` — 変更差分のコードレビュー -- `/ndf:pr-tests` — PR Test Plan の自動実行 diff --git a/plugins/ndf-claude/skills/issue-plan-strategy/SKILL.md b/plugins/ndf-claude/skills/issue-plan-strategy/SKILL.md index fdae1ecb..add1e621 100644 --- a/plugins/ndf-claude/skills/issue-plan-strategy/SKILL.md +++ b/plugins/ndf-claude/skills/issue-plan-strategy/SKILL.md @@ -251,7 +251,7 @@ release ブランチへの merge が一通り進んだ段階で: - PR 間の API / 型 / スキーマ整合 - 設定値の重複・矛盾 - migration の順序依存 - - E2E シナリオ (`/ndf:playwright-scenario-test` の活用) + - E2E シナリオ (`/ndf:playwright-planning` の活用) - ここで **新たに** 個別 PR 範囲のバグが見つかった場合は、**release PR にコメントせず**、該当の個別 PR (既に merge 済みなら修正差分を載せた新しい修正 PR を release 配下に作成) 側に指摘を書き込み、修正ループを回す。この場合レビュー対象は **修正差分** であり新規 PR でレビューできる(元の差分がそもそも cross-review 未実施だったケースは扱いが異なるため Step 8 のフォールバック参照) - release PR には integration 観点の指摘のみ残す @@ -355,4 +355,4 @@ git checkout release/ - `/ndf:cherry-pick-pr` — 検証ブランチへの cherry-pick PR - `/ndf:review` / `/ndf:review-branch` / `/ndf:cross-review` — レビュー - `/ndf:fix` / `/ndf:resolve-pr-comments` — コメント対応 -- `/ndf:playwright-scenario-test` — release ブランチでの E2E 結合テスト +- `/ndf:playwright-planning` — release ブランチでの E2E 結合テスト diff --git a/plugins/ndf-claude/skills/playwright-authoring/SKILL.md b/plugins/ndf-claude/skills/playwright-authoring/SKILL.md new file mode 100644 index 00000000..32754982 --- /dev/null +++ b/plugins/ndf-claude/skills/playwright-authoring/SKILL.md @@ -0,0 +1,250 @@ +--- +name: playwright-authoring +description: "Create reproducible Playwright test scripts and run them with evidence, or check a page over browser MCP. Use when writing E2E test code, running E2E tests, doing a browser smoke check, or connecting to a remote Chrome over CDP (テストスクリプト作成 / テスト実行 / ブラウザ動作確認 / CDP 接続)." +when_to_use: "テストコード実装 / エビデンス動画・trace 収集 / accessibility・Core Web Vitals 計測 / ブラウザ接続先の変更が必要なとき。Triggers: 'playwright codegen', 'pwk_evidence', 'axe-core', 'WCAG', 'LCP', 'CLS', 'body_check', 'overlay', 'connectOverCDP', 'host.docker.internal', 'remote debugging'" +argument-hint: "[url]" +allowed-tools: + - Read + - Edit + - Write + - Bash + - mcp__playwright__browser_navigate + - mcp__playwright__browser_snapshot + - mcp__playwright__browser_click + - mcp__playwright__browser_fill_form + - mcp__playwright__browser_take_screenshot + - mcp__playwright__browser_type + - mcp__playwright__browser_evaluate + - mcp__playwright__browser_console_messages + - mcp__playwright__browser_wait_for + - mcp__playwright__browser_tabs + - mcp__playwright__browser_navigate_back + - mcp__playwright__browser_close + - mcp__playwright__browser_resize + - mcp__playwright__browser_handle_dialog + - mcp__playwright__browser_press_key + - mcp__playwright__browser_hover + - mcp__playwright__browser_select_option + - mcp__playwright__browser_drag + - mcp__playwright__browser_network_requests + - mcp__playwright__browser_file_upload + - mcp__playwright__browser_install + - mcp__chrome-devtools__navigate_page + - mcp__chrome-devtools__take_snapshot + - mcp__chrome-devtools__click + - mcp__chrome-devtools__fill_form + - mcp__chrome-devtools__take_screenshot + - mcp__chrome-devtools__type + - mcp__chrome-devtools__evaluate_script + - mcp__chrome-devtools__list_console_messages + - mcp__chrome-devtools__wait_for + - mcp__chrome-devtools__list_pages + - mcp__chrome-devtools__new_page + - mcp__chrome-devtools__select_page + - mcp__chrome-devtools__close_page + - mcp__chrome-devtools__navigate_page_history + - mcp__chrome-devtools__resize_page + - mcp__chrome-devtools__handle_dialog + - mcp__chrome-devtools__hover + - mcp__chrome-devtools__drag + - mcp__chrome-devtools__list_network_requests + - mcp__chrome-devtools__get_network_request + - mcp__chrome-devtools__upload_file + - mcp__chrome-devtools__emulate_network + - mcp__chrome-devtools__emulate_cpu + - mcp__chrome-devtools__performance_start_trace + - mcp__chrome-devtools__performance_stop_trace + - mcp__chrome-devtools__performance_analyze_insight +--- + +# Playwright スクリプト作成と実行 + +再現可能なテストスクリプトを作成し、レビューを経てから実行してエビデンスを収集する。 +スクリプトを介さない単発のブラウザ動作確認は「MCP でのブラウザ動作確認」節で行う。 + +## 大原則 + +1. **テストスクリプトを実装してからテストを実施する。** レビューを通るまで実行フェーズに進まない +2. **エビデンス動画はデフォルト ON。** 明示的にスキップする場合のみ `--pwk-no-video` を指定する +3. **`scenario-test/` は ndf plugin 非依存。** プラグイン未インストール環境でも単体で動く + +## 前提条件 + +- テスト計画が完了していること (`/ndf:playwright-planning`) +- `init_project.sh` でプロジェクトが初期化済みであること (`/ndf:playwright-kit-ops`) +- `scenario.config.yaml` が設定済みであること + +## ワークフロー + +``` +[A] テスト計画の確認 (チェックリスト / page role / テスト技法) + ▼ +[B] テンプレート選択 tests/ 配下の test_*.py を起点にする + ▼ +[C] テストコード実装 codegen で記録 → expect() ベースの assertion を追加 + ▼ +[D] 再現可能性レビュー 下記チェックリストを全項目確認 + ▼ +[E] テスト実行 + エビデンス収集 ./scenario-test/run.sh + ▼ +[F] レポートと証跡へ → /ndf:playwright-evidence +``` + +## テストスクリプト作成 + +### テンプレートを起点にする + +`init_project.sh` で以下のテンプレートが `tests/` に配置済み。プロジェクト固有の URL やセレクタを書き換えて使う。 + +| テンプレート | page role | 内容 | +|---|---|---| +| `test_auth.py` | auth | ログイン / ログアウトフロー | +| `test_list.py` | list | 一覧ページネーション / ソート | +| `test_form.py` | form | 入力 → 送信 → 結果検証 | +| `test_dashboard.py` | dashboard | KPI / リンク遷移 | + +→ コード例は `playwright-kit-ops/templates/test_*.py.template` を参照。 + +### playwright codegen での操作記録 + +`uv run playwright codegen ` で操作を記録し、生成コードをテスト関数にコピーする。 +コピー後に `@pytest.mark.page_role()`, `@pytest.mark.role()`, `expect()` assertion, `pwk_config.base_url` を追加する。 + +### fixture / marker + +完全な一覧は `playwright_kit/pytest_plugin.py` の `_PWK_MARKERS` 定義と `playwright_kit/fixtures/` 配下を参照。 + +- 主な fixture: `pwk_config`, `pwk_role_`, `pwk_evidence`, `pwk_accessibility_scan()`, `pwk_web_vitals_measure()` +- 主な marker: `@pytest.mark.page_role()`, `@pytest.mark.role()`, `@pytest.mark.phase()`, `@pytest.mark.priority()`, `@pytest.mark.no_body_check` + +overlay API (`set_caption`, `flash_click`, `hide_cursor`) の使用例は `playwright_kit/overlay.py` を参照。 + +### 再現可能性レビューチェックリスト + +スクリプト完成後、以下を全項目確認してからテスト実行に進む。 + +- [ ] **再現可能性**: 同じ環境で同じ結果が得られるか (ランダム値・タイムスタンプに依存していないか) +- [ ] **テストデータ独立性**: 外部の状態に依存せず、テスト単体で成立するか +- [ ] **marker 付与**: `@pytest.mark.page_role()` が全テスト関数に付与されているか +- [ ] **role marker**: 認証が必要なテストに `@pytest.mark.role()` + `pwk_role_` fixture があるか +- [ ] **assertion 網羅性**: 正常系 + 少なくとも 1 つの異常系 (バリデーション等) が含まれるか +- [ ] **URL 構築**: ハードコードされた URL ではなく `pwk_config.base_url` を使用しているか +- [ ] **wait 戦略**: `wait_until="domcontentloaded"` 等の明示的な待機指定があるか +- [ ] **ndf plugin 非依存**: `scenario-test/` ディレクトリ単体で実行可能か + +## テスト実行 + +```bash +./scenario-test/run.sh # 全テスト (動画 ON) +./scenario-test/run.sh -k test_admin # フィルタ +./scenario-test/run.sh --pwk-overlay # 字幕 + カーソル付き動画 +./scenario-test/run.sh --pwk-no-video # 動画のみ OFF +./scenario-test/run.sh --pwk-no-evidence # 全エビデンス OFF (HAR/trace/動画) +``` + +### CLI options + +| option | 役割 | +|---|---| +| `--pwk-config ` | `scenario.config.yaml` のパス | +| `--pwk-out-dir ` | 成果物出力先 (default: `reports//`) | +| `--pwk-no-video` | 動画収集を OFF (デフォルトは ON) | +| `--pwk-no-evidence` | HAR / trace / video の収集を全て OFF | +| `--pwk-har-mode {minimal,full,none}` | HAR 録画モード (default: minimal) | +| `--pwk-overlay` | overlay (赤丸カーソル + 字幕) を ON | +| `--pwk-drive-folder=` | 実行後に Drive へ自動アップロード (→ `/ndf:playwright-evidence`) | + +### エビデンス種別と成果物 + +| 種別 | デフォルト | OFF フラグ | 説明 | +|---|---|---|---| +| video | **ON** | `--pwk-no-video` | 全テストの動画を取得 | +| trace | ON (retain-on-failure) | `--pwk-no-evidence` | Playwright Trace (DOM + 操作ログ) | +| HAR | ON (minimal) | `--pwk-har-mode none` | ネットワーク通信ログ | +| screenshot | ON (only-on-failure) | `--pwk-no-evidence` | 失敗時スクリーンショット | + +``` +reports// +├── report.md # テスト結果サマリ +├── / +│ ├── video.mp4 # テスト動画 (デフォルト ON) +│ ├── trace.zip # Playwright Trace +│ ├── request.har # ネットワーク通信ログ +│ ├── body_check.jsonl # body_check 違反詳細 +│ └── screenshot-*.png # スクリーンショット +``` + +### 品質計測 + +いずれも `scenario.config.yaml` で制御する。設定例は `playwright-kit-ops/templates/scenario.config.yaml` を参照。 + +| 計測 | 発動条件 | 設定セクション | +|---|---|---| +| accessibility (axe-core) | `@pytest.mark.page_role` が auto_roles にマッチ | `accessibility:` | +| Core Web Vitals (LCP/CLS/TTFB/longest_task) | 同上 | `web_vitals:` | +| body_check (PHP/SSR エラー検出) | 常時有効。`@pytest.mark.no_body_check` で opt-out | `body_check:` | + +body_check は `page.on("response")` で全 HTML レスポンスを監視し、`Fatal error` 等を検出する。 + +## ブラウザ接続 + +| モード | scenario.config.yaml | 接続先 | 用途 | +|---|---|---|---| +| `local` | `browser.mode: local` | コンテナ内 Chromium | CI / ヘッドレス実行 (デフォルト) | +| `cdp-remote` | `browser.mode: cdp-remote` | リモート Chrome (CDP) | GUI 操作・ログイン済み Session 再利用 | + +```yaml +browser: + # local: playwright install chromium でインストールしたローカルブラウザ (デフォルト) + # cdp-remote: Chrome DevTools Protocol 経由でリモートブラウザに接続 + mode: local + # cdp-remote 時のみ有効 + cdp_endpoint: ${CDP_ENDPOINT:-http://localhost:9222} +``` + +WSL2 / macOS / Linux ホストの Chrome へ CDP 接続する手順、`scripts/start-host-chrome.sh` によるホスト +Chrome の起動、`conftest.py` への統合、ネットワーク到達性の確保、トラブルシュートは +[references/browser-connection.md](references/browser-connection.md) を参照。 + +## MCP でのブラウザ動作確認 + +テストスクリプトを書かずに、現在のブランチの実装をブラウザで確認する手順。Playwright MCP または +Chrome DevTools MCP の利用可能な方を自動選択する。どちらも使えない環境では手動確認手順を案内する。 + +``` +/ndf:playwright-authoring # 現在のブランチの実装を確認 +/ndf:playwright-authoring http://localhost:8080 # 特定 URL を確認 +``` + +| MCP | 特徴 | 前提 | +|---|---|---| +| Playwright MCP | 自動でブラウザを起動。Chromium/Firefox/WebKit 対応。利用可能なら第一選択 | Playwright インストール | +| Chrome DevTools MCP | 既に開いている Chrome を操作。DevTools 統合でパフォーマンス分析可能 | Chrome をデバッグモードで起動 (`--remote-debugging-port=9222`) | + +### 手順 + +1. **アプリケーション起動確認**: `docker compose ps` や `curl -fsS http://localhost:/health` で確認する。起動していなければ起動手順を案内する +2. **アクセスと認証**: 指定 URL (または `/`) にアクセスし、必要ならログインする。資格情報はプロジェクト固有で、`.env.example` / README から確認し機密情報として扱う +3. **機能画面への遷移**: 実装された機能に応じた画面へ遷移する +4. **動作確認**: フォーム入力・ボタンクリック・データ表示・コンソールエラー・ネットワークリクエストを確認する。スクリーンショットは明示的に指示されたときのみ取得する +5. **結果報告**: 実施項目 / 確認事項 (コンソールエラー・ネットワークエラー・期待結果との一致) / 気になる点 を Markdown で報告する + +継続的に回すべき確認は、この手順で得た操作列をテストスクリプトへ落とし込む (本 Skill の前半)。 + +## ndf plugin 非依存 + +`init_project.sh` で埋め込まれた `scenario-test/` は `playwright_kit/` パッケージ本体を含み、 +`pyproject.toml` で pytest11 entry-point を定義し、`run.sh` でワンコマンド実行できる。 +→ ndf plugin 未インストール環境でも `./scenario-test/run.sh` で動作する。 + +## 関連 Skill + +- `/ndf:playwright-planning` — テスト計画 (前段) +- `/ndf:playwright-evidence` — 証跡とレポート (後段) +- `/ndf:playwright-kit-ops` — 実行環境の運用 (init_project / codegen / スキャン) +- `/ndf:docker-container-access` — Docker コンテナアクセス一般 +- `/ndf:review-branch` — 変更差分のコードレビュー +- `/ndf:pr-tests` — PR Test Plan の自動実行 + +> `playwright-planning` / `playwright-evidence` / `playwright-kit-ops` は Codex 公開セットに同梱される。 +> Claude Code / Kiro CLI では `plugins/ndf-shared/skills/` を直接参照する。 diff --git a/plugins/ndf-shared/skills/playwright-browser-connect/SKILL.md b/plugins/ndf-claude/skills/playwright-authoring/references/browser-connection.md similarity index 50% rename from plugins/ndf-shared/skills/playwright-browser-connect/SKILL.md rename to plugins/ndf-claude/skills/playwright-authoring/references/browser-connection.md index 0607b6cc..29e7d4de 100644 --- a/plugins/ndf-shared/skills/playwright-browser-connect/SKILL.md +++ b/plugins/ndf-claude/skills/playwright-authoring/references/browser-connection.md @@ -1,39 +1,25 @@ ---- -name: playwright-browser-connect -description: "Configure Playwright browser and CDP connections." -when_to_use: "E2E テストのブラウザ接続先を設定・変更するとき / remote Chrome に CDP で接続したいとき / WSL2 Docker から Windows Chrome を操作したいとき / macOS ホストの Chrome を使いたいとき。Triggers: 'ブラウザ接続', 'remote chrome', 'CDP接続', 'connectOverCDP', 'リモートブラウザ', 'Windows Chrome', 'macOS Chrome', 'mac Chrome', 'browser connect', 'cdp endpoint', 'remote debugging', 'コンテナからホスト Chrome 起動', 'host.docker.internal'" -allowed-tools: - - Read - - Bash ---- +# ブラウザ接続構成 (local / CDP remote) -# Playwright Browser Connect (ブラウザ接続構成) +E2E テスト実行時のブラウザ接続先を構成する手順。概要と設定項目は `SKILL.md` の「ブラウザ接続」節を参照。 -E2E テスト実行時のブラウザ接続先を構成する。 +## Chrome 起動フラグ -## 接続モード一覧 +CDP 接続に使う Chrome は次のフラグで起動する。OS ごとの差はバイナリパスだけである。 -| モード | scenario.config.yaml | 接続先 | 用途 | -|---|---|---|---| -| `local` | `browser.mode: local` | コンテナ内 Chromium | CI / ヘッドレス実行 (デフォルト) | -| `cdp-remote` | `browser.mode: cdp-remote` | リモート Chrome (CDP) | GUI 操作・ログイン済み Session 再利用 | - -## 設定 (scenario.config.yaml) - -```yaml -# --- ブラウザ接続設定 -------------------------------------------------- -browser: - # local: playwright install chromium でインストールしたローカルブラウザ (デフォルト) - # cdp-remote: Chrome DevTools Protocol 経由でリモートブラウザに接続 - mode: local +| フラグ | 役割 | +|---|---| +| `--remote-debugging-port=9222` | CDP エンドポイントを 9222 で公開 | +| `--remote-allow-origins=*` | CDP WebSocket の Host ヘッダ検証を無効化し、コンテナ等リモートからの接続を許可 (Chrome 106+) | +| `--user-data-dir=/tmp/chrome-debug` | 専用プロファイルで起動し、通常の Chrome と共存させる。任意のパスでよい | +| `--disable-features=DialMediaRouteProvider` | DIAL (Cast) 探索を無効化し、CDP ログのノイズと不要な通信を抑制 | +| `--remote-debugging-address=0.0.0.0` | 全インターフェースで listen する。loopback bind でコンテナから届かない場合のみ付与 | - # cdp-remote 時のみ有効 - cdp_endpoint: ${CDP_ENDPOINT:-http://localhost:9222} -``` +既存プロファイルのログイン済み Session をそのまま使う場合は、**全 Chrome プロセスを終了してから** +`--user-data-dir` を外して起動する (デフォルトプロファイルを使用)。 -## パターン別セットアップ +> **Security**: `--remote-allow-origins=*` と `--remote-debugging-address=0.0.0.0` は信頼できるネットワーク内でのみ使用する。ファイアウォールでポート 9222 へのアクセスを制限することを推奨。 -### パターン 1: ローカルコンテナ Chromium (デフォルト) +## パターン 1: ローカルコンテナ Chromium (デフォルト) 設定不要。`run.sh` 初回実行時に `playwright install chromium` が自動実行される。 @@ -42,65 +28,28 @@ browser: mode: local ``` -### パターン 2: Windows ホスト Chrome (WSL2 + Docker → CDP) - -WSL2 上の Docker コンテナから Windows 側の Chrome GUI を CDP 経由で操作する。 - -#### 構成図 +## パターン 2: Windows ホスト Chrome (WSL2 + Docker → CDP) ``` Docker container (playwright) ↓ http://host.docker.internal:9222 -Docker Desktop (WSL2 backend) - ↓ host.docker.internal → Windows host IP -Windows host - ↓ localhost:9222 +Docker Desktop (WSL2 backend) → Windows host → localhost:9222 + ↓ Chrome (--remote-debugging-port=9222 --remote-allow-origins=*) ``` -#### セットアップ手順 - **Step 1: Windows Chrome をリモートデバッグモードで起動** ```powershell -# Windows PowerShell -& "C:\Program Files\Google\Chrome\Application\chrome.exe" ` - --remote-debugging-port=9222 ` - --remote-allow-origins=* ` - --user-data-dir="C:\tmp\chrome-debug" -``` - -既存プロファイルのログイン済み Session を使う場合: - -```powershell -# 全 Chrome プロセスを閉じてから -& "C:\Program Files\Google\Chrome\Application\chrome.exe" ` - --remote-debugging-port=9222 ` - --remote-allow-origins=* -``` - -**Step 2: `--remote-allow-origins=*` で Host ヘッダ検証を無効化** - -Chrome CDP の WebSocket は Host ヘッダ検証があるため、リモートからの接続がデフォルトで拒否される。 -Chrome 起動時に `--remote-allow-origins=*` フラグを付けることで、任意の Origin からの接続を許可できる。 - -Step 1 のコマンドにフラグを追加: - -```powershell -# Windows PowerShell & "C:\Program Files\Google\Chrome\Application\chrome.exe" ` --remote-debugging-port=9222 ` --remote-allow-origins=* ` --user-data-dir="C:\tmp\chrome-debug" ``` -これにより proxy を設置する必要がなくなり、Docker コンテナから直接 CDP エンドポイントに接続できる。 - -> **Note**: `--remote-allow-origins=*` は Chrome 106+ で利用可能。セキュリティ上、信頼できるネットワーク内での利用に限定すること。 +> Chrome はデフォルトで `127.0.0.1` にバインドするため、`--remote-allow-origins=*` だけでは WSL2/Docker から接続できない場合がある。その場合は後述の「ネットワーク別接続ガイド」で到達性を確保する。 -> **Important**: Chrome はデフォルトで `127.0.0.1` にバインドするため、`--remote-allow-origins=*` だけでは WSL2/Docker から接続できない場合がある。対処方法は「ネットワーク別接続ガイド」セクションを参照。 - -**Step 3: WSL2 .wslconfig (NAT mode 確認)** +**Step 2: WSL2 .wslconfig を NAT mode にする** ```ini # %USERPROFILE%\.wslconfig @@ -108,7 +57,7 @@ Step 1 のコマンドにフラグを追加: networkingMode=NAT ``` -**Step 4: scenario.config.yaml** +**Step 3: scenario.config.yaml** Docker Desktop (WSL2 backend) は `host.docker.internal` を標準サポートしている。 @@ -118,37 +67,22 @@ browser: cdp_endpoint: ${CDP_ENDPOINT:-http://host.docker.internal:9222} ``` -環境変数で指定する場合: - -```bash -export CDP_ENDPOINT="http://host.docker.internal:9222" -``` - -> **Note (Docker Desktop を使わず WSL2 から直接実行する場合)**: `host.docker.internal` は Docker Desktop 固有の DNS 名のため利用できない。代わりに Windows ホストの IP アドレスを直接指定する: +> **Docker Desktop を使わず WSL2 から直接実行する場合**: `host.docker.internal` は Docker Desktop 固有の DNS 名のため使えない。Windows ホストの IP を直接指定する。 > ```bash -> # WSL2 から Windows ホスト IP を取得 -> export CDP_ENDPOINT="http://$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}'):9222" +> export CDP_ENDPOINT="http://$(grep nameserver /etc/resolv.conf | awk '{print $2}'):9222" > ``` -### パターン 3: macOS ホスト Chrome (Docker → CDP) - -macOS 上の Docker コンテナから macOS 側の Chrome GUI を CDP 経由で操作する。 - -#### 構成図 +## パターン 3: macOS ホスト Chrome (Docker → CDP) ``` Docker container (playwright) ↓ http://host.docker.internal:9222 -macOS host - ↓ localhost:9222 +macOS host → localhost:9222 + ↓ Chrome (--remote-debugging-port=9222 --remote-allow-origins=*) ``` -#### セットアップ手順 - -**Step 1: macOS Chrome をリモートデバッグモードで起動 (ホスト側で実行)** - -実績のある起動コマンド: +**Step 1: ホスト側で Chrome を起動** ```bash "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \ @@ -158,31 +92,10 @@ Chrome (--remote-debugging-port=9222 --remote-allow-origins=*) --disable-features=DialMediaRouteProvider ``` -各フラグの意味: - -| フラグ | 役割 | -|---|---| -| `--remote-debugging-port=9222` | CDP エンドポイントを 9222 で公開 | -| `--user-data-dir=/tmp/chrome-debug` | 専用プロファイルで起動 (既存の通常 Chrome と共存可能)。任意のパスでよい | -| `--remote-allow-origins=*` | CDP WebSocket の Host ヘッダ検証を無効化し、リモート (コンテナ) からの接続を許可 (Chrome 106+) | -| `--disable-features=DialMediaRouteProvider` | DIAL (Cast) のメディアルート探索を無効化。CDP ログのノイズと不要なネットワーク探索を抑制 | - -> **Note**: 上記は macOS Docker Desktop で動作実績のあるコマンド。macOS Docker Desktop は `host.docker.internal` がホストの loopback (127.0.0.1) バインドのサービスに到達できるため、`--remote-debugging-address=0.0.0.0` は不要 (全ネットワークインターフェース公開によるセキュリティ低下も避けられる)。Linux / WSL2 ホストで loopback バインドが問題になる場合は `--remote-debugging-address=0.0.0.0` を付与する (`start-host-chrome.sh` では `CDP_BIND_ADDRESS=0.0.0.0` を指定)。詳細は後述の「ネットワーク別接続ガイド」(方法 1: `0.0.0.0` / 方法 2: socat / 方法 3: netsh portproxy) を参照。 - -既存プロファイルのログイン済み Session をそのまま使う場合は、全 Chrome プロセスを終了してから -`--user-data-dir` を外して起動する (デフォルトプロファイルを使用): - -```bash -# 全 Chrome プロセスを終了してから -"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \ - --remote-debugging-port=9222 \ - --remote-allow-origins=* \ - --disable-features=DialMediaRouteProvider -``` +> **Note**: 上記は macOS Docker Desktop で動作実績のあるコマンド。macOS Docker Desktop は `host.docker.internal` がホストの loopback (127.0.0.1) バインドのサービスに到達できるため、`--remote-debugging-address=0.0.0.0` は不要で、全インターフェース公開によるセキュリティ低下も避けられる。Linux / WSL2 ホストで loopback bind が問題になる場合のみ `0.0.0.0` を付与する。 **Step 2: scenario.config.yaml** -macOS Docker Desktop は `host.docker.internal` を標準サポートしており、 `--remote-allow-origins=*` で Host ヘッダ検証を無効化しているため、WSL2 と異なり **proxy 不要**。 ```yaml @@ -191,20 +104,16 @@ browser: cdp_endpoint: ${CDP_ENDPOINT:-http://host.docker.internal:9222} ``` -**Step 3 (任意): コンテナからホスト Chrome を起動する** - -毎回ホスト側で手動起動するのを避けたい場合は、コンテナから SSH 経由でホストの Chrome を起動できる。 -詳細は後述の「コンテナからホスト Chrome を起動する (SSH 経由)」セクションを参照。 +**Step 3 (任意): コンテナからホスト Chrome を起動する** → 次節。 ## コンテナからホスト Chrome を起動する (SSH 経由) ### なぜ直接は起動できないのか Docker コンテナはホストとプロセス空間が分離されているため、**コンテナ内のプロセスがホスト上に直接プロセスを生成することはできない**。 -特に macOS / Windows の Docker Desktop はコンテナを LinuxKit VM 内で実行するため、`nsenter` やホスト PID namespace を使う Linux 系の回避策も VM 止まりで macOS ホストには届かない。 +特に macOS / Windows の Docker Desktop はコンテナを LinuxKit VM 内で実行するため、`nsenter` やホスト PID namespace を使う Linux 系の回避策も VM 止まりでホストには届かない。 したがって「コンテナからホストの Chrome を起動する」には、**ホスト側に起動を受け付ける口** が必要になる。最も導入が容易でスクリプト化しやすいのは **SSH** (macOS の「リモートログイン」= sshd) を使う方法。 -コンテナは `host.docker.internal` でホストに到達できるため、SSH でホストにログインして起動コマンドを実行する。 ``` Docker container ──ssh──▶ host.docker.internal:22 (macOS sshd) @@ -214,69 +123,42 @@ Docker container ──CDP──▶ host.docker.internal:9222 (起動後に接 ### ホスト側の準備 (一度だけ) -1. **リモートログインを有効化**: システム設定 > 一般 > 共有 > 「リモートログイン」を ON - (CLI: `sudo systemsetup -setremotelogin on`) +1. **リモートログインを有効化**: システム設定 > 一般 > 共有 > 「リモートログイン」を ON (CLI: `sudo systemsetup -setremotelogin on`) 2. **SSH 鍵を登録** (パスワードレス実行のため): コンテナ側の公開鍵をホストの `~/.ssh/authorized_keys` に追加 -3. ログインユーザーは **コンソールにログイン中の本人** であること。 - macOS では GUI アプリ (Chrome) は WindowServer に接続するため、コンソールセッションの所有者として起動する必要がある。 +3. ログインユーザーは **コンソールにログイン中の本人** であること。macOS では GUI アプリ (Chrome) は WindowServer に接続するため、コンソールセッションの所有者として起動する必要がある ### スクリプト -`scripts/start-host-chrome.sh` をコンテナ内から実行する。 -冪等で、既に CDP が起動済みなら何もしない。 +`scripts/start-host-chrome.sh` をコンテナ内から実行する。冪等で、既に CDP が起動済みなら何もしない。 ```bash # コンテナ内 -HOST_SSH_USER= \ - ./scripts/start-host-chrome.sh +HOST_SSH_USER= ./scripts/start-host-chrome.sh ``` -主な環境変数: - | 変数 | デフォルト | 説明 | |---|---|---| | `HOST_SSH_USER` | (必須) | ホスト (mac) のログインユーザー名 | | `HOST_SSH_HOST` | `host.docker.internal` | SSH 接続先ホスト | | `CDP_PORT` | `9222` | リモートデバッグポート | -| `CDP_BIND_ADDRESS` | (空=loopback) | Chrome の listen address。空なら付与せず Chrome 既定の loopback bind (macOS Docker Desktop はこれで動作・実証済み)。Linux/WSL2 等で loopback bind だとコンテナから到達できない場合のみ `0.0.0.0` 等を指定 (全インターフェース公開のためセキュリティ注意) | +| `CDP_BIND_ADDRESS` | (空=loopback) | Chrome の listen address。空なら Chrome 既定の loopback bind (macOS Docker Desktop はこれで動作・実証済み)。Linux/WSL2 等で到達できない場合のみ `0.0.0.0` 等を指定 | | `CHROME_USER_DATA_DIR` | `/tmp/chrome-debug` | 起動プロファイル。空にするとデフォルトプロファイル (ログイン済み Session) を使用 | | `CHROME_BIN` | `/Applications/Google Chrome.app/Contents/MacOS/Google Chrome` | Chrome バイナリパス | | `MANUAL_WAIT` | `120` | 手動フォールバック時の起動待ち秒。`0` で待たず即終了 | -スクリプトの動作: +動作: 1. `http://host.docker.internal:9222/json/version` に疎通すれば **起動済み** とみなし即終了 2. 未起動なら SSH (`BatchMode=yes`) でホストに接続し、Chrome をバックグラウンド (`nohup ... &`) で起動 3. CDP エンドポイントが応答するまで最大 30 秒ポーリングして待機 -#### SSH が使えない場合のフォールバック - -以下のいずれかに該当すると、スクリプトは **自動で手動フォールバックに切り替わる**: +### SSH が使えない場合のフォールバック -- `HOST_SSH_USER` が未設定 -- コンテナに `ssh` クライアントが無い -- SSH 接続/実行に失敗 (鍵未登録・リモートログイン無効・到達不可など。`BatchMode=yes` によりパスワード待ちで固まらず即失敗) - -フォールバック時は、**ホスト側で実行すべき起動コマンドをそのまま画面に出力** し、 -`MANUAL_WAIT` 秒 (既定 120s) のあいだ CDP の起動をポーリングして待機する。 -利用者はその間にホストのターミナルへコマンドを貼り付けて実行すればよく、 -起動が検知されればスクリプトは成功終了する。 - -```text -────────────────────────────────────────────────────────────── -⚠ SSH 自動起動を利用できません (SSH 接続/実行に失敗)。 - ホスト (mac) 側のターミナルで以下を実行してください: - - "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" --remote-debugging-port=9222 --user-data-dir='/tmp/chrome-debug' --remote-allow-origins=* --disable-features=DialMediaRouteProvider - -────────────────────────────────────────────────────────────── -→ ホストでの起動を待機中 (最大 120s, Ctrl-C で中断)... -``` +`HOST_SSH_USER` 未設定 / コンテナに `ssh` クライアントが無い / SSH 接続・実行に失敗 (鍵未登録・リモートログイン無効・到達不可) のいずれかで、スクリプトは **自動で手動フォールバックに切り替わる**。 -CI など人手が介在しない環境では `MANUAL_WAIT=0` を指定すれば、案内を出して即座に非ゼロ終了する。 +フォールバック時は、ホスト側で実行すべき起動コマンドをそのまま画面に出力し、`MANUAL_WAIT` 秒 (既定 120s) のあいだ CDP の起動をポーリングして待機する。利用者はその間にホストのターミナルへコマンドを貼り付けて実行すればよい。CI など人手が介在しない環境では `MANUAL_WAIT=0` を指定すれば、案内を出して即座に非ゼロ終了する。 -> **Note (SSH を使わない代替手段)**: ホスト側に常駐ランチャ (launchd エージェントや FIFO 監視スクリプト、簡易 HTTP エンドポイント等) を置き、コンテナからネットワーク経由でトリガする方法もある。 -> ただし SSH 方式が最も追加実装が少なく確実。X11 forwarding (XQuartz + socat) は「コンテナ内 GUI をホスト画面に表示する」用途であり、本件 (ホストの既存 Chrome を起動する) には不要。 +> **Note (SSH を使わない代替手段)**: ホスト側に常駐ランチャ (launchd エージェントや FIFO 監視スクリプト、簡易 HTTP エンドポイント等) を置き、コンテナからネットワーク経由でトリガする方法もある。ただし SSH 方式が最も追加実装が少なく確実。X11 forwarding (XQuartz + socat) は「コンテナ内 GUI をホスト画面に表示する」用途であり、本件には不要。 > **Note (Linux ホストの場合)**: ホストで sshd が動いていれば同じスクリプトが使える。`CHROME_BIN=google-chrome`、`HOST_SSH_HOST` をホスト IP (`172.17.0.1` 等) に設定する。GUI セッションへの接続には `DISPLAY` 等の追加考慮が必要。 @@ -285,7 +167,7 @@ CI など人手が介在しない環境では `MANUAL_WAIT=0` を指定すれば `browser.mode: cdp-remote` の場合、pytest-playwright の通常のブラウザ起動をバイパスし、 `connectOverCDP()` で既存 Chrome に接続する fixture を有効化する必要がある。 -`scenario-test/conftest.py` に以下を追加: +`scenario-test/conftest.py` に以下を追加する。 ```python import pytest @@ -333,9 +215,9 @@ def browser( ### CDP モードでの既存セッション再利用 -`cdp-remote` モードでは、テンプレートの `conftest.py` が `context` / `page` fixture を -自動的にオーバーライドし、CDP 接続先の既存コンテキスト (ログイン済み Session) を返す。 -標準のテストコードは何も変更せずに既存セッションを利用できる。 +`browser.new_context()` は新規コンテキストを作成するため、既存のログイン Session は引き継がれない。 +`cdp-remote` モードでは、テンプレートの `conftest.py` が `context` / `page` fixture を自動的にオーバーライドし、 +CDP 接続先の既存コンテキスト (ログイン済み Session) を返す。標準のテストコードは無変更で既存セッションを利用できる。 ```python @pytest.fixture(scope="session") @@ -359,17 +241,10 @@ def page(context, pwk_config): pg.close() ``` -`browser.new_context()` は新規コンテキストを作成するため、既存のログイン Session は引き継がれない。 -`cdp-remote` モードでは `context` fixture が自動的に `browser.contexts[0]` を返すため、 -テスト側で特別な対応は不要。 - ## run.sh での利用 -`cdp-remote` モード時は `playwright install chromium` が不要。 -`run.sh` は初回セットアップで `playwright install` を実行するが、 -接続先がリモートの場合はスキップして問題ない (ローカルブラウザは使わないため)。 - -CDP 接続テストを手動確認する場合: +`cdp-remote` モード時は `playwright install chromium` が不要。`run.sh` は初回セットアップで +`playwright install` を実行するが、接続先がリモートの場合はスキップして問題ない。 ```bash # エンドポイントの疎通確認 @@ -378,56 +253,30 @@ curl -s http://host.docker.internal:9222/json/version | python3 -m json.tool ## ネットワーク別接続ガイド -Chrome はデフォルトで `127.0.0.1` (ループバック) にバインドするため、同一ホストからしか CDP エンドポイントにアクセスできない。Docker コンテナや WSL2 からリモート接続する場合は、以下のいずれかの方法でネットワーク到達性を確保する必要がある。 +Chrome はデフォルトで `127.0.0.1` にバインドするため、同一ホストからしか CDP エンドポイントにアクセスできない。 +Docker コンテナや WSL2 からリモート接続する場合は、次のいずれかで到達性を確保する。 ### 方法 1: `--remote-debugging-address=0.0.0.0` (推奨) -Chrome 起動時に全インターフェースでリッスンさせる。最もシンプルな方法。 - -```bash -# Linux / macOS -google-chrome \ - --remote-debugging-port=9222 \ - --remote-debugging-address=0.0.0.0 \ - --remote-allow-origins=* -``` - -```powershell -# Windows PowerShell -& "C:\Program Files\Google\Chrome\Application\chrome.exe" ` - --remote-debugging-port=9222 ` - --remote-debugging-address=0.0.0.0 ` - --remote-allow-origins=* -``` - -> **Security**: `0.0.0.0` はすべてのネットワークインターフェースに公開するため、信頼できるネットワーク内でのみ使用すること。ファイアウォールでポート 9222 へのアクセスを制限することを推奨。 +Chrome 起動時に全インターフェースでリッスンさせる。最もシンプル。フラグの詳細は冒頭の表を参照。 ### 方法 2: socat によるポートフォワード (Linux) Chrome を `127.0.0.1` バインドのまま維持し、socat でリモートからのアクセスを中継する。 ```bash -# Chrome は通常どおり起動 (127.0.0.1 バインド) -google-chrome --remote-debugging-port=9222 --remote-allow-origins=* - -# 別ターミナルで socat を起動 socat TCP-LISTEN:9222,bind=0.0.0.0,reuseaddr,fork TCP:127.0.0.1:9222 ``` ### 方法 3: netsh portproxy (Windows → WSL2) -Windows ホストの Chrome を WSL2 からアクセスする場合、Windows 側でポートフォワードを設定する。 - ```powershell # 管理者権限の PowerShell で実行 netsh interface portproxy add v4tov4 ` listenaddress=0.0.0.0 listenport=9222 ` connectaddress=127.0.0.1 connectport=9222 -# 確認 netsh interface portproxy show all - -# 削除する場合 netsh interface portproxy delete v4tov4 listenaddress=0.0.0.0 listenport=9222 ``` @@ -439,7 +288,7 @@ netsh interface portproxy delete v4tov4 listenaddress=0.0.0.0 listenport=9222 | Docker → ホスト (macOS) | macOS ホスト | 方法 1 | `http://host.docker.internal:9222` | | Docker → ホスト (Linux) | Linux ホスト | 方法 1 or 2 | `http://host.docker.internal:9222` or `http://172.17.0.1:9222` | | Docker (WSL2) → Windows | Windows ホスト | 方法 1 or 3 | `http://host.docker.internal:9222` | -| WSL2 → Windows | Windows ホスト | 方法 1 or 3 | `http://$(cat /etc/resolv.conf \| grep nameserver \| awk '{print $2}'):9222` | +| WSL2 → Windows | Windows ホスト | 方法 1 or 3 | `http://$(grep nameserver /etc/resolv.conf \| awk '{print $2}'):9222` | ## トラブルシュート @@ -456,7 +305,7 @@ netsh interface portproxy delete v4tov4 listenaddress=0.0.0.0 listenport=9222 | 症状 | 原因 | 対策 | |---|---|---| | `host.docker.internal` 解決不能 | Docker Desktop 未使用 or 古いバージョン | Docker Desktop を使用するか、WSL2 直接の場合は Windows ホスト IP を直接指定 | -| IPv6 でバインドされる | WSL2 が IPv6 優先 | proxy.js で `0.0.0.0` を明示 | +| IPv6 でバインドされる | WSL2 が IPv6 優先 | listen address に `0.0.0.0` を明示 | | `netsh portproxy` で接続ループ | portproxy の自己参照 | `--remote-allow-origins=*` を使い proxy を廃止 | | mirrored mode で動かない | mirrored は localhost 共有だが CDP の WS 接続でポート競合 | NAT mode に戻す | @@ -466,7 +315,7 @@ netsh interface portproxy delete v4tov4 listenaddress=0.0.0.0 listenport=9222 |---|---|---| | `host.docker.internal` 解決不能 | Docker Desktop が古い / Linux Docker | `--add-host=host.docker.internal:host-gateway` を指定 | | ファイアウォールでブロック | macOS のアプリファイアウォール | システム設定 > ネットワーク > ファイアウォール で Chrome を許可 | -| SSH 起動で Chrome が表示されない / WindowServer エラー | コンソール非ログインユーザーで SSH した | コンソールにログイン中の本人ユーザーで SSH する (`start-host-chrome.sh` 参照) | +| SSH 起動で Chrome が表示されない / WindowServer エラー | コンソール非ログインユーザーで SSH した | コンソールにログイン中の本人ユーザーで SSH する | | `start-host-chrome.sh` が SSH で認証失敗 | リモートログイン未有効 / 鍵未登録 | `sudo systemsetup -setremotelogin on` と `authorized_keys` 登録を確認 | ## CDP 接続のメリット @@ -475,10 +324,3 @@ netsh interface portproxy delete v4tov4 listenaddress=0.0.0.0 listenport=9222 - **ログイン済み Session の再利用** — Google / AWS / Slack 等の MFA 済み Session をそのまま使える - **ブラウザ拡張機能が有効** — テスト時にも拡張機能の影響を確認可能 - **AI Agent との相性** — Claude Code / Browser Use / OpenHands がリアルブラウザを操作 - -## 関連 Skill - -- `/ndf:playwright-execution` — テスト実行 + エビデンス収集 -- `/ndf:playwright-kit-ops` — プロジェクト初期化 / ツール群 -- `/ndf:playwright-scenario-test` — 全機能統括 -- `/ndf:docker-container-access` — Docker コンテナアクセス一般 diff --git a/plugins/ndf-shared/skills/playwright-browser-connect/scripts/start-host-chrome.sh b/plugins/ndf-claude/skills/playwright-authoring/scripts/start-host-chrome.sh similarity index 100% rename from plugins/ndf-shared/skills/playwright-browser-connect/scripts/start-host-chrome.sh rename to plugins/ndf-claude/skills/playwright-authoring/scripts/start-host-chrome.sh diff --git a/plugins/ndf-codex/skills/issue-plan-strategy/SKILL.md b/plugins/ndf-codex/skills/issue-plan-strategy/SKILL.md index fdae1ecb..add1e621 100644 --- a/plugins/ndf-codex/skills/issue-plan-strategy/SKILL.md +++ b/plugins/ndf-codex/skills/issue-plan-strategy/SKILL.md @@ -251,7 +251,7 @@ release ブランチへの merge が一通り進んだ段階で: - PR 間の API / 型 / スキーマ整合 - 設定値の重複・矛盾 - migration の順序依存 - - E2E シナリオ (`/ndf:playwright-scenario-test` の活用) + - E2E シナリオ (`/ndf:playwright-planning` の活用) - ここで **新たに** 個別 PR 範囲のバグが見つかった場合は、**release PR にコメントせず**、該当の個別 PR (既に merge 済みなら修正差分を載せた新しい修正 PR を release 配下に作成) 側に指摘を書き込み、修正ループを回す。この場合レビュー対象は **修正差分** であり新規 PR でレビューできる(元の差分がそもそも cross-review 未実施だったケースは扱いが異なるため Step 8 のフォールバック参照) - release PR には integration 観点の指摘のみ残す @@ -355,4 +355,4 @@ git checkout release/ - `/ndf:cherry-pick-pr` — 検証ブランチへの cherry-pick PR - `/ndf:review` / `/ndf:review-branch` / `/ndf:cross-review` — レビュー - `/ndf:fix` / `/ndf:resolve-pr-comments` — コメント対応 -- `/ndf:playwright-scenario-test` — release ブランチでの E2E 結合テスト +- `/ndf:playwright-planning` — release ブランチでの E2E 結合テスト diff --git a/plugins/ndf-codex/skills/playwright-authoring/SKILL.md b/plugins/ndf-codex/skills/playwright-authoring/SKILL.md new file mode 100644 index 00000000..32754982 --- /dev/null +++ b/plugins/ndf-codex/skills/playwright-authoring/SKILL.md @@ -0,0 +1,250 @@ +--- +name: playwright-authoring +description: "Create reproducible Playwright test scripts and run them with evidence, or check a page over browser MCP. Use when writing E2E test code, running E2E tests, doing a browser smoke check, or connecting to a remote Chrome over CDP (テストスクリプト作成 / テスト実行 / ブラウザ動作確認 / CDP 接続)." +when_to_use: "テストコード実装 / エビデンス動画・trace 収集 / accessibility・Core Web Vitals 計測 / ブラウザ接続先の変更が必要なとき。Triggers: 'playwright codegen', 'pwk_evidence', 'axe-core', 'WCAG', 'LCP', 'CLS', 'body_check', 'overlay', 'connectOverCDP', 'host.docker.internal', 'remote debugging'" +argument-hint: "[url]" +allowed-tools: + - Read + - Edit + - Write + - Bash + - mcp__playwright__browser_navigate + - mcp__playwright__browser_snapshot + - mcp__playwright__browser_click + - mcp__playwright__browser_fill_form + - mcp__playwright__browser_take_screenshot + - mcp__playwright__browser_type + - mcp__playwright__browser_evaluate + - mcp__playwright__browser_console_messages + - mcp__playwright__browser_wait_for + - mcp__playwright__browser_tabs + - mcp__playwright__browser_navigate_back + - mcp__playwright__browser_close + - mcp__playwright__browser_resize + - mcp__playwright__browser_handle_dialog + - mcp__playwright__browser_press_key + - mcp__playwright__browser_hover + - mcp__playwright__browser_select_option + - mcp__playwright__browser_drag + - mcp__playwright__browser_network_requests + - mcp__playwright__browser_file_upload + - mcp__playwright__browser_install + - mcp__chrome-devtools__navigate_page + - mcp__chrome-devtools__take_snapshot + - mcp__chrome-devtools__click + - mcp__chrome-devtools__fill_form + - mcp__chrome-devtools__take_screenshot + - mcp__chrome-devtools__type + - mcp__chrome-devtools__evaluate_script + - mcp__chrome-devtools__list_console_messages + - mcp__chrome-devtools__wait_for + - mcp__chrome-devtools__list_pages + - mcp__chrome-devtools__new_page + - mcp__chrome-devtools__select_page + - mcp__chrome-devtools__close_page + - mcp__chrome-devtools__navigate_page_history + - mcp__chrome-devtools__resize_page + - mcp__chrome-devtools__handle_dialog + - mcp__chrome-devtools__hover + - mcp__chrome-devtools__drag + - mcp__chrome-devtools__list_network_requests + - mcp__chrome-devtools__get_network_request + - mcp__chrome-devtools__upload_file + - mcp__chrome-devtools__emulate_network + - mcp__chrome-devtools__emulate_cpu + - mcp__chrome-devtools__performance_start_trace + - mcp__chrome-devtools__performance_stop_trace + - mcp__chrome-devtools__performance_analyze_insight +--- + +# Playwright スクリプト作成と実行 + +再現可能なテストスクリプトを作成し、レビューを経てから実行してエビデンスを収集する。 +スクリプトを介さない単発のブラウザ動作確認は「MCP でのブラウザ動作確認」節で行う。 + +## 大原則 + +1. **テストスクリプトを実装してからテストを実施する。** レビューを通るまで実行フェーズに進まない +2. **エビデンス動画はデフォルト ON。** 明示的にスキップする場合のみ `--pwk-no-video` を指定する +3. **`scenario-test/` は ndf plugin 非依存。** プラグイン未インストール環境でも単体で動く + +## 前提条件 + +- テスト計画が完了していること (`/ndf:playwright-planning`) +- `init_project.sh` でプロジェクトが初期化済みであること (`/ndf:playwright-kit-ops`) +- `scenario.config.yaml` が設定済みであること + +## ワークフロー + +``` +[A] テスト計画の確認 (チェックリスト / page role / テスト技法) + ▼ +[B] テンプレート選択 tests/ 配下の test_*.py を起点にする + ▼ +[C] テストコード実装 codegen で記録 → expect() ベースの assertion を追加 + ▼ +[D] 再現可能性レビュー 下記チェックリストを全項目確認 + ▼ +[E] テスト実行 + エビデンス収集 ./scenario-test/run.sh + ▼ +[F] レポートと証跡へ → /ndf:playwright-evidence +``` + +## テストスクリプト作成 + +### テンプレートを起点にする + +`init_project.sh` で以下のテンプレートが `tests/` に配置済み。プロジェクト固有の URL やセレクタを書き換えて使う。 + +| テンプレート | page role | 内容 | +|---|---|---| +| `test_auth.py` | auth | ログイン / ログアウトフロー | +| `test_list.py` | list | 一覧ページネーション / ソート | +| `test_form.py` | form | 入力 → 送信 → 結果検証 | +| `test_dashboard.py` | dashboard | KPI / リンク遷移 | + +→ コード例は `playwright-kit-ops/templates/test_*.py.template` を参照。 + +### playwright codegen での操作記録 + +`uv run playwright codegen ` で操作を記録し、生成コードをテスト関数にコピーする。 +コピー後に `@pytest.mark.page_role()`, `@pytest.mark.role()`, `expect()` assertion, `pwk_config.base_url` を追加する。 + +### fixture / marker + +完全な一覧は `playwright_kit/pytest_plugin.py` の `_PWK_MARKERS` 定義と `playwright_kit/fixtures/` 配下を参照。 + +- 主な fixture: `pwk_config`, `pwk_role_`, `pwk_evidence`, `pwk_accessibility_scan()`, `pwk_web_vitals_measure()` +- 主な marker: `@pytest.mark.page_role()`, `@pytest.mark.role()`, `@pytest.mark.phase()`, `@pytest.mark.priority()`, `@pytest.mark.no_body_check` + +overlay API (`set_caption`, `flash_click`, `hide_cursor`) の使用例は `playwright_kit/overlay.py` を参照。 + +### 再現可能性レビューチェックリスト + +スクリプト完成後、以下を全項目確認してからテスト実行に進む。 + +- [ ] **再現可能性**: 同じ環境で同じ結果が得られるか (ランダム値・タイムスタンプに依存していないか) +- [ ] **テストデータ独立性**: 外部の状態に依存せず、テスト単体で成立するか +- [ ] **marker 付与**: `@pytest.mark.page_role()` が全テスト関数に付与されているか +- [ ] **role marker**: 認証が必要なテストに `@pytest.mark.role()` + `pwk_role_` fixture があるか +- [ ] **assertion 網羅性**: 正常系 + 少なくとも 1 つの異常系 (バリデーション等) が含まれるか +- [ ] **URL 構築**: ハードコードされた URL ではなく `pwk_config.base_url` を使用しているか +- [ ] **wait 戦略**: `wait_until="domcontentloaded"` 等の明示的な待機指定があるか +- [ ] **ndf plugin 非依存**: `scenario-test/` ディレクトリ単体で実行可能か + +## テスト実行 + +```bash +./scenario-test/run.sh # 全テスト (動画 ON) +./scenario-test/run.sh -k test_admin # フィルタ +./scenario-test/run.sh --pwk-overlay # 字幕 + カーソル付き動画 +./scenario-test/run.sh --pwk-no-video # 動画のみ OFF +./scenario-test/run.sh --pwk-no-evidence # 全エビデンス OFF (HAR/trace/動画) +``` + +### CLI options + +| option | 役割 | +|---|---| +| `--pwk-config ` | `scenario.config.yaml` のパス | +| `--pwk-out-dir ` | 成果物出力先 (default: `reports//`) | +| `--pwk-no-video` | 動画収集を OFF (デフォルトは ON) | +| `--pwk-no-evidence` | HAR / trace / video の収集を全て OFF | +| `--pwk-har-mode {minimal,full,none}` | HAR 録画モード (default: minimal) | +| `--pwk-overlay` | overlay (赤丸カーソル + 字幕) を ON | +| `--pwk-drive-folder=` | 実行後に Drive へ自動アップロード (→ `/ndf:playwright-evidence`) | + +### エビデンス種別と成果物 + +| 種別 | デフォルト | OFF フラグ | 説明 | +|---|---|---|---| +| video | **ON** | `--pwk-no-video` | 全テストの動画を取得 | +| trace | ON (retain-on-failure) | `--pwk-no-evidence` | Playwright Trace (DOM + 操作ログ) | +| HAR | ON (minimal) | `--pwk-har-mode none` | ネットワーク通信ログ | +| screenshot | ON (only-on-failure) | `--pwk-no-evidence` | 失敗時スクリーンショット | + +``` +reports// +├── report.md # テスト結果サマリ +├── / +│ ├── video.mp4 # テスト動画 (デフォルト ON) +│ ├── trace.zip # Playwright Trace +│ ├── request.har # ネットワーク通信ログ +│ ├── body_check.jsonl # body_check 違反詳細 +│ └── screenshot-*.png # スクリーンショット +``` + +### 品質計測 + +いずれも `scenario.config.yaml` で制御する。設定例は `playwright-kit-ops/templates/scenario.config.yaml` を参照。 + +| 計測 | 発動条件 | 設定セクション | +|---|---|---| +| accessibility (axe-core) | `@pytest.mark.page_role` が auto_roles にマッチ | `accessibility:` | +| Core Web Vitals (LCP/CLS/TTFB/longest_task) | 同上 | `web_vitals:` | +| body_check (PHP/SSR エラー検出) | 常時有効。`@pytest.mark.no_body_check` で opt-out | `body_check:` | + +body_check は `page.on("response")` で全 HTML レスポンスを監視し、`Fatal error` 等を検出する。 + +## ブラウザ接続 + +| モード | scenario.config.yaml | 接続先 | 用途 | +|---|---|---|---| +| `local` | `browser.mode: local` | コンテナ内 Chromium | CI / ヘッドレス実行 (デフォルト) | +| `cdp-remote` | `browser.mode: cdp-remote` | リモート Chrome (CDP) | GUI 操作・ログイン済み Session 再利用 | + +```yaml +browser: + # local: playwright install chromium でインストールしたローカルブラウザ (デフォルト) + # cdp-remote: Chrome DevTools Protocol 経由でリモートブラウザに接続 + mode: local + # cdp-remote 時のみ有効 + cdp_endpoint: ${CDP_ENDPOINT:-http://localhost:9222} +``` + +WSL2 / macOS / Linux ホストの Chrome へ CDP 接続する手順、`scripts/start-host-chrome.sh` によるホスト +Chrome の起動、`conftest.py` への統合、ネットワーク到達性の確保、トラブルシュートは +[references/browser-connection.md](references/browser-connection.md) を参照。 + +## MCP でのブラウザ動作確認 + +テストスクリプトを書かずに、現在のブランチの実装をブラウザで確認する手順。Playwright MCP または +Chrome DevTools MCP の利用可能な方を自動選択する。どちらも使えない環境では手動確認手順を案内する。 + +``` +/ndf:playwright-authoring # 現在のブランチの実装を確認 +/ndf:playwright-authoring http://localhost:8080 # 特定 URL を確認 +``` + +| MCP | 特徴 | 前提 | +|---|---|---| +| Playwright MCP | 自動でブラウザを起動。Chromium/Firefox/WebKit 対応。利用可能なら第一選択 | Playwright インストール | +| Chrome DevTools MCP | 既に開いている Chrome を操作。DevTools 統合でパフォーマンス分析可能 | Chrome をデバッグモードで起動 (`--remote-debugging-port=9222`) | + +### 手順 + +1. **アプリケーション起動確認**: `docker compose ps` や `curl -fsS http://localhost:/health` で確認する。起動していなければ起動手順を案内する +2. **アクセスと認証**: 指定 URL (または `/`) にアクセスし、必要ならログインする。資格情報はプロジェクト固有で、`.env.example` / README から確認し機密情報として扱う +3. **機能画面への遷移**: 実装された機能に応じた画面へ遷移する +4. **動作確認**: フォーム入力・ボタンクリック・データ表示・コンソールエラー・ネットワークリクエストを確認する。スクリーンショットは明示的に指示されたときのみ取得する +5. **結果報告**: 実施項目 / 確認事項 (コンソールエラー・ネットワークエラー・期待結果との一致) / 気になる点 を Markdown で報告する + +継続的に回すべき確認は、この手順で得た操作列をテストスクリプトへ落とし込む (本 Skill の前半)。 + +## ndf plugin 非依存 + +`init_project.sh` で埋め込まれた `scenario-test/` は `playwright_kit/` パッケージ本体を含み、 +`pyproject.toml` で pytest11 entry-point を定義し、`run.sh` でワンコマンド実行できる。 +→ ndf plugin 未インストール環境でも `./scenario-test/run.sh` で動作する。 + +## 関連 Skill + +- `/ndf:playwright-planning` — テスト計画 (前段) +- `/ndf:playwright-evidence` — 証跡とレポート (後段) +- `/ndf:playwright-kit-ops` — 実行環境の運用 (init_project / codegen / スキャン) +- `/ndf:docker-container-access` — Docker コンテナアクセス一般 +- `/ndf:review-branch` — 変更差分のコードレビュー +- `/ndf:pr-tests` — PR Test Plan の自動実行 + +> `playwright-planning` / `playwright-evidence` / `playwright-kit-ops` は Codex 公開セットに同梱される。 +> Claude Code / Kiro CLI では `plugins/ndf-shared/skills/` を直接参照する。 diff --git a/plugins/ndf-codex/skills/playwright-authoring/references/browser-connection.md b/plugins/ndf-codex/skills/playwright-authoring/references/browser-connection.md new file mode 100644 index 00000000..29e7d4de --- /dev/null +++ b/plugins/ndf-codex/skills/playwright-authoring/references/browser-connection.md @@ -0,0 +1,326 @@ +# ブラウザ接続構成 (local / CDP remote) + +E2E テスト実行時のブラウザ接続先を構成する手順。概要と設定項目は `SKILL.md` の「ブラウザ接続」節を参照。 + +## Chrome 起動フラグ + +CDP 接続に使う Chrome は次のフラグで起動する。OS ごとの差はバイナリパスだけである。 + +| フラグ | 役割 | +|---|---| +| `--remote-debugging-port=9222` | CDP エンドポイントを 9222 で公開 | +| `--remote-allow-origins=*` | CDP WebSocket の Host ヘッダ検証を無効化し、コンテナ等リモートからの接続を許可 (Chrome 106+) | +| `--user-data-dir=/tmp/chrome-debug` | 専用プロファイルで起動し、通常の Chrome と共存させる。任意のパスでよい | +| `--disable-features=DialMediaRouteProvider` | DIAL (Cast) 探索を無効化し、CDP ログのノイズと不要な通信を抑制 | +| `--remote-debugging-address=0.0.0.0` | 全インターフェースで listen する。loopback bind でコンテナから届かない場合のみ付与 | + +既存プロファイルのログイン済み Session をそのまま使う場合は、**全 Chrome プロセスを終了してから** +`--user-data-dir` を外して起動する (デフォルトプロファイルを使用)。 + +> **Security**: `--remote-allow-origins=*` と `--remote-debugging-address=0.0.0.0` は信頼できるネットワーク内でのみ使用する。ファイアウォールでポート 9222 へのアクセスを制限することを推奨。 + +## パターン 1: ローカルコンテナ Chromium (デフォルト) + +設定不要。`run.sh` 初回実行時に `playwright install chromium` が自動実行される。 + +```yaml +browser: + mode: local +``` + +## パターン 2: Windows ホスト Chrome (WSL2 + Docker → CDP) + +``` +Docker container (playwright) + ↓ http://host.docker.internal:9222 +Docker Desktop (WSL2 backend) → Windows host → localhost:9222 + ↓ +Chrome (--remote-debugging-port=9222 --remote-allow-origins=*) +``` + +**Step 1: Windows Chrome をリモートデバッグモードで起動** + +```powershell +& "C:\Program Files\Google\Chrome\Application\chrome.exe" ` + --remote-debugging-port=9222 ` + --remote-allow-origins=* ` + --user-data-dir="C:\tmp\chrome-debug" +``` + +> Chrome はデフォルトで `127.0.0.1` にバインドするため、`--remote-allow-origins=*` だけでは WSL2/Docker から接続できない場合がある。その場合は後述の「ネットワーク別接続ガイド」で到達性を確保する。 + +**Step 2: WSL2 .wslconfig を NAT mode にする** + +```ini +# %USERPROFILE%\.wslconfig +[wsl2] +networkingMode=NAT +``` + +**Step 3: scenario.config.yaml** + +Docker Desktop (WSL2 backend) は `host.docker.internal` を標準サポートしている。 + +```yaml +browser: + mode: cdp-remote + cdp_endpoint: ${CDP_ENDPOINT:-http://host.docker.internal:9222} +``` + +> **Docker Desktop を使わず WSL2 から直接実行する場合**: `host.docker.internal` は Docker Desktop 固有の DNS 名のため使えない。Windows ホストの IP を直接指定する。 +> ```bash +> export CDP_ENDPOINT="http://$(grep nameserver /etc/resolv.conf | awk '{print $2}'):9222" +> ``` + +## パターン 3: macOS ホスト Chrome (Docker → CDP) + +``` +Docker container (playwright) + ↓ http://host.docker.internal:9222 +macOS host → localhost:9222 + ↓ +Chrome (--remote-debugging-port=9222 --remote-allow-origins=*) +``` + +**Step 1: ホスト側で Chrome を起動** + +```bash +"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \ + --remote-debugging-port=9222 \ + --user-data-dir=/tmp/chrome-debug \ + --remote-allow-origins=* \ + --disable-features=DialMediaRouteProvider +``` + +> **Note**: 上記は macOS Docker Desktop で動作実績のあるコマンド。macOS Docker Desktop は `host.docker.internal` がホストの loopback (127.0.0.1) バインドのサービスに到達できるため、`--remote-debugging-address=0.0.0.0` は不要で、全インターフェース公開によるセキュリティ低下も避けられる。Linux / WSL2 ホストで loopback bind が問題になる場合のみ `0.0.0.0` を付与する。 + +**Step 2: scenario.config.yaml** + +`--remote-allow-origins=*` で Host ヘッダ検証を無効化しているため、WSL2 と異なり **proxy 不要**。 + +```yaml +browser: + mode: cdp-remote + cdp_endpoint: ${CDP_ENDPOINT:-http://host.docker.internal:9222} +``` + +**Step 3 (任意): コンテナからホスト Chrome を起動する** → 次節。 + +## コンテナからホスト Chrome を起動する (SSH 経由) + +### なぜ直接は起動できないのか + +Docker コンテナはホストとプロセス空間が分離されているため、**コンテナ内のプロセスがホスト上に直接プロセスを生成することはできない**。 +特に macOS / Windows の Docker Desktop はコンテナを LinuxKit VM 内で実行するため、`nsenter` やホスト PID namespace を使う Linux 系の回避策も VM 止まりでホストには届かない。 + +したがって「コンテナからホストの Chrome を起動する」には、**ホスト側に起動を受け付ける口** が必要になる。最も導入が容易でスクリプト化しやすいのは **SSH** (macOS の「リモートログイン」= sshd) を使う方法。 + +``` +Docker container ──ssh──▶ host.docker.internal:22 (macOS sshd) + └─▶ Google Chrome --remote-debugging-port=9222 ... (バックグラウンド起動) +Docker container ──CDP──▶ host.docker.internal:9222 (起動後に接続) +``` + +### ホスト側の準備 (一度だけ) + +1. **リモートログインを有効化**: システム設定 > 一般 > 共有 > 「リモートログイン」を ON (CLI: `sudo systemsetup -setremotelogin on`) +2. **SSH 鍵を登録** (パスワードレス実行のため): コンテナ側の公開鍵をホストの `~/.ssh/authorized_keys` に追加 +3. ログインユーザーは **コンソールにログイン中の本人** であること。macOS では GUI アプリ (Chrome) は WindowServer に接続するため、コンソールセッションの所有者として起動する必要がある + +### スクリプト + +`scripts/start-host-chrome.sh` をコンテナ内から実行する。冪等で、既に CDP が起動済みなら何もしない。 + +```bash +# コンテナ内 +HOST_SSH_USER= ./scripts/start-host-chrome.sh +``` + +| 変数 | デフォルト | 説明 | +|---|---|---| +| `HOST_SSH_USER` | (必須) | ホスト (mac) のログインユーザー名 | +| `HOST_SSH_HOST` | `host.docker.internal` | SSH 接続先ホスト | +| `CDP_PORT` | `9222` | リモートデバッグポート | +| `CDP_BIND_ADDRESS` | (空=loopback) | Chrome の listen address。空なら Chrome 既定の loopback bind (macOS Docker Desktop はこれで動作・実証済み)。Linux/WSL2 等で到達できない場合のみ `0.0.0.0` 等を指定 | +| `CHROME_USER_DATA_DIR` | `/tmp/chrome-debug` | 起動プロファイル。空にするとデフォルトプロファイル (ログイン済み Session) を使用 | +| `CHROME_BIN` | `/Applications/Google Chrome.app/Contents/MacOS/Google Chrome` | Chrome バイナリパス | +| `MANUAL_WAIT` | `120` | 手動フォールバック時の起動待ち秒。`0` で待たず即終了 | + +動作: + +1. `http://host.docker.internal:9222/json/version` に疎通すれば **起動済み** とみなし即終了 +2. 未起動なら SSH (`BatchMode=yes`) でホストに接続し、Chrome をバックグラウンド (`nohup ... &`) で起動 +3. CDP エンドポイントが応答するまで最大 30 秒ポーリングして待機 + +### SSH が使えない場合のフォールバック + +`HOST_SSH_USER` 未設定 / コンテナに `ssh` クライアントが無い / SSH 接続・実行に失敗 (鍵未登録・リモートログイン無効・到達不可) のいずれかで、スクリプトは **自動で手動フォールバックに切り替わる**。 + +フォールバック時は、ホスト側で実行すべき起動コマンドをそのまま画面に出力し、`MANUAL_WAIT` 秒 (既定 120s) のあいだ CDP の起動をポーリングして待機する。利用者はその間にホストのターミナルへコマンドを貼り付けて実行すればよい。CI など人手が介在しない環境では `MANUAL_WAIT=0` を指定すれば、案内を出して即座に非ゼロ終了する。 + +> **Note (SSH を使わない代替手段)**: ホスト側に常駐ランチャ (launchd エージェントや FIFO 監視スクリプト、簡易 HTTP エンドポイント等) を置き、コンテナからネットワーク経由でトリガする方法もある。ただし SSH 方式が最も追加実装が少なく確実。X11 forwarding (XQuartz + socat) は「コンテナ内 GUI をホスト画面に表示する」用途であり、本件には不要。 + +> **Note (Linux ホストの場合)**: ホストで sshd が動いていれば同じスクリプトが使える。`CHROME_BIN=google-chrome`、`HOST_SSH_HOST` をホスト IP (`172.17.0.1` 等) に設定する。GUI セッションへの接続には `DISPLAY` 等の追加考慮が必要。 + +## conftest.py への統合 + +`browser.mode: cdp-remote` の場合、pytest-playwright の通常のブラウザ起動をバイパスし、 +`connectOverCDP()` で既存 Chrome に接続する fixture を有効化する必要がある。 + +`scenario-test/conftest.py` に以下を追加する。 + +```python +import pytest +from playwright.sync_api import Browser, BrowserType + +@pytest.fixture(scope="session") +def browser( + browser_type: BrowserType, + browser_type_launch_args: dict, + pwk_config, +) -> Browser: + """browser.mode に応じてブラウザ接続を切り替える。 + + - local: pytest-playwright デフォルト (chromium.launch()) + - cdp-remote: chromium.connect_over_cdp(endpoint) + """ + browser_cfg = pwk_config.browser + # slow_mo: browser_type_launch_args が優先、なければ config の slow_mo_ms + _slow_mo = browser_type_launch_args.get( + "slow_mo", pwk_config.playwright.slow_mo_ms or None + ) + if browser_cfg.mode == "cdp-remote": + if browser_type.name != "chromium": + pytest.fail( + f"cdp-remote モードは Chromium 専用です (現在: {browser_type.name})。" + "--browser chromium を指定するか、browser.mode を local に変更してください。" + ) + browser = browser_type.connect_over_cdp( + browser_cfg.cdp_endpoint, + slow_mo=_slow_mo, + ) + yield browser + # CDP 接続の場合、close() は接続を切断 (disconnect) するだけで、 + # リモートブラウザ自体は終了しない。 + browser.close() + else: + launch_args = {**browser_type_launch_args} + launch_args.setdefault("headless", pwk_config.playwright.headless) + if _slow_mo is not None: + launch_args.setdefault("slow_mo", _slow_mo) + browser = browser_type.launch(**launch_args) + yield browser + browser.close() +``` + +### CDP モードでの既存セッション再利用 + +`browser.new_context()` は新規コンテキストを作成するため、既存のログイン Session は引き継がれない。 +`cdp-remote` モードでは、テンプレートの `conftest.py` が `context` / `page` fixture を自動的にオーバーライドし、 +CDP 接続先の既存コンテキスト (ログイン済み Session) を返す。標準のテストコードは無変更で既存セッションを利用できる。 + +```python +@pytest.fixture(scope="session") +def context(browser, pwk_config, _cdp_default_context): + """cdp-remote: 既存コンテキスト / local: 新規コンテキスト""" + if pwk_config.browser.mode == "cdp-remote" and _cdp_default_context is not None: + yield _cdp_default_context + else: + ctx = browser.new_context() + yield ctx + ctx.close() + +@pytest.fixture(scope="session") +def page(context, pwk_config): + """cdp-remote: 既存ページ / local: 新規ページ""" + if pwk_config.browser.mode == "cdp-remote" and context.pages: + yield context.pages[0] + else: + pg = context.new_page() + yield pg + pg.close() +``` + +## run.sh での利用 + +`cdp-remote` モード時は `playwright install chromium` が不要。`run.sh` は初回セットアップで +`playwright install` を実行するが、接続先がリモートの場合はスキップして問題ない。 + +```bash +# エンドポイントの疎通確認 +curl -s http://host.docker.internal:9222/json/version | python3 -m json.tool +``` + +## ネットワーク別接続ガイド + +Chrome はデフォルトで `127.0.0.1` にバインドするため、同一ホストからしか CDP エンドポイントにアクセスできない。 +Docker コンテナや WSL2 からリモート接続する場合は、次のいずれかで到達性を確保する。 + +### 方法 1: `--remote-debugging-address=0.0.0.0` (推奨) + +Chrome 起動時に全インターフェースでリッスンさせる。最もシンプル。フラグの詳細は冒頭の表を参照。 + +### 方法 2: socat によるポートフォワード (Linux) + +Chrome を `127.0.0.1` バインドのまま維持し、socat でリモートからのアクセスを中継する。 + +```bash +socat TCP-LISTEN:9222,bind=0.0.0.0,reuseaddr,fork TCP:127.0.0.1:9222 +``` + +### 方法 3: netsh portproxy (Windows → WSL2) + +```powershell +# 管理者権限の PowerShell で実行 +netsh interface portproxy add v4tov4 ` + listenaddress=0.0.0.0 listenport=9222 ` + connectaddress=127.0.0.1 connectport=9222 + +netsh interface portproxy show all +netsh interface portproxy delete v4tov4 listenaddress=0.0.0.0 listenport=9222 +``` + +### 接続先の早見表 + +| 実行環境 | Chrome の場所 | 推奨方法 | CDP エンドポイント | +|---|---|---|---| +| ローカル (同一ホスト) | 同一ホスト | 設定不要 | `http://localhost:9222` | +| Docker → ホスト (macOS) | macOS ホスト | 方法 1 | `http://host.docker.internal:9222` | +| Docker → ホスト (Linux) | Linux ホスト | 方法 1 or 2 | `http://host.docker.internal:9222` or `http://172.17.0.1:9222` | +| Docker (WSL2) → Windows | Windows ホスト | 方法 1 or 3 | `http://host.docker.internal:9222` | +| WSL2 → Windows | Windows ホスト | 方法 1 or 3 | `http://$(grep nameserver /etc/resolv.conf \| awk '{print $2}'):9222` | + +## トラブルシュート + +### 共通 + +| 症状 | 原因 | 対策 | +|---|---|---| +| `connect_over_cdp` で接続拒否 | Chrome が起動していない / ポートが違う | `curl http:///json/version` で確認 | +| WebSocket handshake 失敗 | Host ヘッダ不一致 | Chrome 起動時に `--remote-allow-origins=*` を付与 | +| ページ操作が異常に遅い | VPN / DNS 解決の遅延 | `extra_hosts` で IP 直指定 | + +### Windows (WSL2) 固有 + +| 症状 | 原因 | 対策 | +|---|---|---| +| `host.docker.internal` 解決不能 | Docker Desktop 未使用 or 古いバージョン | Docker Desktop を使用するか、WSL2 直接の場合は Windows ホスト IP を直接指定 | +| IPv6 でバインドされる | WSL2 が IPv6 優先 | listen address に `0.0.0.0` を明示 | +| `netsh portproxy` で接続ループ | portproxy の自己参照 | `--remote-allow-origins=*` を使い proxy を廃止 | +| mirrored mode で動かない | mirrored は localhost 共有だが CDP の WS 接続でポート競合 | NAT mode に戻す | + +### macOS 固有 + +| 症状 | 原因 | 対策 | +|---|---|---| +| `host.docker.internal` 解決不能 | Docker Desktop が古い / Linux Docker | `--add-host=host.docker.internal:host-gateway` を指定 | +| ファイアウォールでブロック | macOS のアプリファイアウォール | システム設定 > ネットワーク > ファイアウォール で Chrome を許可 | +| SSH 起動で Chrome が表示されない / WindowServer エラー | コンソール非ログインユーザーで SSH した | コンソールにログイン中の本人ユーザーで SSH する | +| `start-host-chrome.sh` が SSH で認証失敗 | リモートログイン未有効 / 鍵未登録 | `sudo systemsetup -setremotelogin on` と `authorized_keys` 登録を確認 | + +## CDP 接続のメリット + +- **GUI Chrome をそのまま操作可能** — OBS 録画可、人間と AI の協調操作が可能 +- **ログイン済み Session の再利用** — Google / AWS / Slack 等の MFA 済み Session をそのまま使える +- **ブラウザ拡張機能が有効** — テスト時にも拡張機能の影響を確認可能 +- **AI Agent との相性** — Claude Code / Browser Use / OpenHands がリアルブラウザを操作 diff --git a/plugins/ndf-codex/skills/playwright-authoring/scripts/start-host-chrome.sh b/plugins/ndf-codex/skills/playwright-authoring/scripts/start-host-chrome.sh new file mode 100755 index 00000000..8c7b1d08 --- /dev/null +++ b/plugins/ndf-codex/skills/playwright-authoring/scripts/start-host-chrome.sh @@ -0,0 +1,172 @@ +#!/usr/bin/env bash +# コンテナ内から SSH 経由でホスト (macOS / Linux) の Chrome を +# リモートデバッグモードで起動するスクリプト。 +# +# 背景: +# Docker コンテナはホストとプロセス空間が分離されているため、 +# コンテナから直接ホストのプロセスを起動できない。 +# ホストの sshd (macOS: システム設定 > 共有 > リモートログイン) に接続し、 +# 起動コマンドを実行することで間接的にホスト Chrome を起動する。 +# +# SSH が使えない場合 (鍵未登録・リモートログイン無効など) は、 +# ホスト側で手動実行する起動コマンドを案内し、起動されるまで待機する +# フォールバックに切り替わる。 +# +# 前提 (SSH 自動起動を使う場合のみ・ホスト側で一度だけ設定): +# 1) リモートログインを有効化 (macOS: sudo systemsetup -setremotelogin on) +# 2) コンテナの公開鍵を ~/.ssh/authorized_keys に登録 (パスワードレス実行) +# 3) コンソールにログイン中の本人ユーザーで SSH すること +# (GUI アプリは WindowServer 接続のためコンソールセッション所有者が必要) +# +# 使い方 (コンテナ内): +# # SSH 自動起動 +# HOST_SSH_USER= ./scripts/start-host-chrome.sh +# # SSH を使わず手動起動の案内のみ +# ./scripts/start-host-chrome.sh +# +# 環境変数: +# HOST_SSH_USER ホストのログインユーザー名。未設定なら手動フォールバック +# HOST_SSH_HOST SSH 接続先 (default: host.docker.internal) +# CDP_HOST CDP 疎通確認先ホスト (default: HOST_SSH_HOST) +# CDP_PORT リモートデバッグポート (default: 9222) +# CDP_BIND_ADDRESS Chrome の listen address。空 (default) なら付与せず +# Chrome 既定の loopback bind (macOS Docker Desktop は +# host.docker.internal がホスト loopback に到達するため +# これで動作する)。Linux/WSL2 等で loopback bind だと +# コンテナから到達できない場合のみ 0.0.0.0 等を指定する。 +# 0.0.0.0 は全インターフェース公開のためセキュリティ注意。 +# CHROME_USER_DATA_DIR 起動プロファイル (default: /tmp/chrome-debug) +# 空にするとデフォルトプロファイル (ログイン済み Session) を使用 +# CHROME_BIN Chrome バイナリパス +# (default: /Applications/Google Chrome.app/Contents/MacOS/Google Chrome) +# STARTUP_TIMEOUT SSH 起動後の待機タイムアウト秒 (default: 30) +# MANUAL_WAIT 手動フォールバック時の待機秒。0 で待たず即終了 (default: 120) +set -euo pipefail + +HOST_SSH_USER="${HOST_SSH_USER:-}" +HOST_SSH_HOST="${HOST_SSH_HOST:-host.docker.internal}" +CDP_HOST="${CDP_HOST:-$HOST_SSH_HOST}" +CDP_PORT="${CDP_PORT:-9222}" +CDP_BIND_ADDRESS="${CDP_BIND_ADDRESS:-}" +CHROME_USER_DATA_DIR="${CHROME_USER_DATA_DIR-/tmp/chrome-debug}" +CHROME_BIN="${CHROME_BIN:-/Applications/Google Chrome.app/Contents/MacOS/Google Chrome}" +STARTUP_TIMEOUT="${STARTUP_TIMEOUT:-30}" +MANUAL_WAIT="${MANUAL_WAIT:-120}" + +# curl は冪等チェック・起動待機・手動フォールバックの全経路で CDP 疎通確認に +# 使う必須コマンド。無いと終了コード 127 で常に未起動扱いとなり、起動成功時でも +# タイムアウトしてしまうため、ここでフェイルファストする。 +if ! command -v curl >/dev/null 2>&1; then + echo "✗ curl が見つかりません。CDP 疎通確認に必須です。" >&2 + echo " コンテナに curl をインストールしてから再実行してください" >&2 + echo " (例: apt-get install -y curl / apk add curl)。" >&2 + exit 1 +fi + +cdp_up() { + # --max-time でネットワークハング時も待機ループ周期が壊れないようにする + curl -sf --max-time 2 "http://${CDP_HOST}:${CDP_PORT}/json/version" >/dev/null 2>&1 +} + +# --user-data-dir は空文字なら付与しない (デフォルトプロファイル使用) +userdata_arg="" +if [ -n "${CHROME_USER_DATA_DIR}" ]; then + userdata_arg="--user-data-dir='${CHROME_USER_DATA_DIR}'" +fi + +# --remote-debugging-address は CDP_BIND_ADDRESS が空なら付与しない。 +# 既定 (空) では Chrome は loopback (127.0.0.1) のみ listen する。macOS +# Docker Desktop は host.docker.internal がホストの loopback に到達するため +# これで動作する (ユーザー実証済み・0.0.0.0 不要)。 +# Linux/WSL2 等で loopback bind だとコンテナから到達できない場合のみ +# CDP_BIND_ADDRESS=0.0.0.0 等を指定する。0.0.0.0 は CDP を全インターフェース +# へ公開し、CDP は認証なしでブラウザ操作できるためセキュリティに注意すること。 +bind_arg="" +if [ -n "${CDP_BIND_ADDRESS}" ]; then + bind_arg="--remote-debugging-address=${CDP_BIND_ADDRESS} " +fi + +# ホスト側で実行する Chrome 起動コマンド (人間がコピペできる体裁) +host_launch_cmd() { + printf '"%s" --remote-debugging-port=%s %s%s --remote-allow-origins=* --disable-features=DialMediaRouteProvider' \ + "${CHROME_BIN}" "${CDP_PORT}" "${bind_arg}" "${userdata_arg}" +} + +# 手動フォールバック: ホストで実行するコマンドを案内し、起動を待機する +manual_fallback() { + local reason="$1" + echo "" >&2 + echo "──────────────────────────────────────────────────────────────" >&2 + echo "⚠ SSH 自動起動を利用できません (${reason})。" >&2 + echo " ホスト (mac) 側のターミナルで以下を実行してください:" >&2 + echo "" >&2 + echo " $(host_launch_cmd)" >&2 + echo "" >&2 + echo "──────────────────────────────────────────────────────────────" >&2 + + if [ "${MANUAL_WAIT}" -le 0 ]; then + echo "✗ Chrome 未起動のまま終了します (MANUAL_WAIT=0)。" >&2 + exit 1 + fi + + echo "→ ホストでの起動を待機中 (最大 ${MANUAL_WAIT}s, Ctrl-C で中断)..." >&2 + # seq 外部依存も bash 専用 for ((...)) も避け、POSIX 互換 while で待機する + # (最小コンテナ / /bin/sh しかない環境でも動作) + i=0 + while [ "$i" -lt "$MANUAL_WAIT" ]; do + if cdp_up; then + echo "✓ Chrome 起動を検知しました: http://${CDP_HOST}:${CDP_PORT}" + exit 0 + fi + sleep 1 + i=$((i + 1)) + done + echo "✗ 待機タイムアウト。手動起動後に再実行してください。" >&2 + exit 1 +} + +# 1) 既に起動済みなら何もしない (冪等) +if cdp_up; then + echo "✓ Chrome は既に CDP http://${CDP_HOST}:${CDP_PORT} で起動済みです" + exit 0 +fi + +# 2) HOST_SSH_USER 未設定 → 手動フォールバック +if [ -z "${HOST_SSH_USER}" ]; then + manual_fallback "HOST_SSH_USER が未設定" +fi + +# 3) ssh コマンドが無い → 手動フォールバック +if ! command -v ssh >/dev/null 2>&1; then + manual_fallback "コンテナに ssh クライアントが無い" +fi + +# 4) SSH でホストに接続し、Chrome をバックグラウンド起動 +echo "→ ${HOST_SSH_USER}@${HOST_SSH_HOST} で Chrome を起動します..." +# &2 +exit 1 diff --git a/plugins/ndf-codex/skills/playwright-evidence/SKILL.md b/plugins/ndf-codex/skills/playwright-evidence/SKILL.md new file mode 100644 index 00000000..f66d8edc --- /dev/null +++ b/plugins/ndf-codex/skills/playwright-evidence/SKILL.md @@ -0,0 +1,172 @@ +--- +name: playwright-evidence +description: "Generate the Playwright test report and store its evidence on Google Drive. Use when generating report.md, sharing E2E test results, or uploading video / trace / HAR evidence to Drive (テストレポート / テスト結果共有 / テスト報告書 / エビデンス保管 / Drive アップロード)." +when_to_use: "レポート生成 / エビデンスのチーム配布 / Drive リンクを埋め込んだ Google Docs 作成が必要なとき。Triggers: 'report.md', 'pwk-drive-folder', 'upload_evidence', 'gdrive_upload_dir', 'trace viewer', 'report を Docs に'" +allowed-tools: + - Read + - Bash(python *) + - Bash(uv *) + - Bash(pytest *) +--- + +# Playwright 証跡とレポート + +テスト実行後に Markdown レポートを生成し、エビデンス一式を Google Drive に保管して共有可能にする。 + +## 前提条件 + +- テスト実行済みで `reports//` にエビデンスが存在すること (`/ndf:playwright-authoring`) +- Drive へ保管する場合のみ、`/ndf:google-auth` で OAuth2 認証が完了していること (drive.file スコープ) + +## レポート生成 + +`pytest_terminal_summary` hook で `reports//report.md` が自動生成される。特別な設定は不要。 + +```bash +./scenario-test/run.sh +# → reports//report.md が生成される +``` + +| セクション | 内容 | +|---|---| +| サマリ表 | nodeid, role, page_role, 結果, 実行時間, エラー数 | +| 失敗詳細 | FAIL/ERROR のテストごとの詳細情報 | +| body_check 違反 | PHP/SSR エラー検出の詳細 (URL, パターン, スニペット) | +| エビデンスリンク | video, trace, HAR, screenshot へのパス | + +`scenario.config.yaml` の `report` セクションで表題等を制御する。 + +```yaml +report: + title: "シナリオ E2E テスト 実施報告書" + test_plan_link: "./test-plan.md" + phase_labels: {} +``` + +## アップロード対象とセキュリティ + +| ファイル | 種別 | セキュリティ考慮 | +|---|---|---| +| `video.mp4` | テスト動画 | 画面に表示された情報が含まれる | +| `trace.zip` | Playwright Trace | DOM snapshot + 操作ログ + Cookie/localStorage | +| `request.har` | ネットワーク通信ログ | HTTP request/response body を含む場合あり | +| `report.md` | テスト結果サマリ | URL + テスト名程度 | +| `body_check.jsonl` | PHP/SSR エラー詳細 | ソースコード片を含む場合あり | +| `screenshot-*.png` | 失敗時スクリーンショット | 画面に表示された情報 | + +**セキュリティ注意**: trace.zip / HAR には認証情報 (Cookie, localStorage, Basic Auth) や +入力内容が含まれる可能性がある。アップロード先は **private folder** + **信頼できる共有相手** に限定すること。 + +## 方法 1: テスト実行時の自動アップロード + +`--pwk-drive-folder` を指定すると `pytest_sessionfinish` hook で自動アップロードされる。 + +```bash +./scenario-test/run.sh --pwk-drive-folder= +``` + +`report.md` と各テストの `trace.zip` / `*.har` / `*.mp4` / `body_check.jsonl` が、 +すべて非公開 (private) でアップロードされる。 + +## 方法 2: 手動アップロード (scripts) + +スクリプトは `playwright-kit-ops/scripts/` に配置されている。 + +```bash +cd scenario-test + +# 単一ファイル +uv run python scripts/upload_evidence.py reports//test_login/trace.zip \ + --kind trace --parent-folder-id + +# ディレクトリ一括 (構造を保ったまま Drive にミラー。サブフォルダも再帰作成) +uv run python scripts/gdrive_upload_dir.py --local reports// --parent + +# report.md → Google Docs 変換 (表・リスト・見出しを Docs ネイティブ形式へ) +uv run python scripts/upload_md_as_gdoc.py --md reports//report.md \ + --parent --name "E2E テスト報告書" + +# Google Docs にエビデンスの Drive リンクを埋め込み +uv run python scripts/build_gdoc_with_drive_links.py --md reports//report.md \ + --folder --run-id --name "E2E テスト報告書" +``` + +`upload_evidence.py` の主なオプション: + +- `--kind {trace|har|video|any}` — ファイル種別 (拡張子から自動判定も可) +- `--parent-folder-id ` — Drive 上のアップロード先フォルダ ID +- `--public` — anyone/read 権限を付与 (trace viewer URL 生成に必要) + +`build_gdoc_with_drive_links.py` は、Drive 上の `` フォルダのファイル一覧を取得し、 +`report.md` 内の相対パスリンク (`./TC-XX/trace.zip`) を Drive URL に書き換えてから Docs 化する。 +チームメンバーは Docs 上で report を読みながらエビデンスへのリンクをクリックできる。 + +## 推奨ワークフロー + +``` +[テスト実行] ./scenario-test/run.sh --pwk-overlay + ▼ +[ローカル確認] reports//report.md で結果確認 + ▼ +[Drive 一括保管] gdrive_upload_dir.py --local reports// --parent + ▼ +[Docs 化 + リンク埋め込み] build_gdoc_with_drive_links.py ... + ▼ +[共有] Docs URL をチーム (Slack / Google Chat) に共有 +``` + +ワンコマンドで済ませる場合: `./scenario-test/run.sh --pwk-drive-folder= --pwk-overlay` + +### Drive フォルダ構成の推奨 + +``` +E2E テスト証跡/ ← 共有ドライブ or チームフォルダ +├── <プロジェクト名>/ +│ ├── 20260526-134500/ ← run-id (自動生成) +│ │ ├── report.md +│ │ └── test_login/ +│ │ ├── video.mp4 +│ │ ├── trace.zip +│ │ └── request.har +│ └── report (Google Docs) ← build_gdoc_with_drive_links で生成 +``` + +## Trace Viewer 連携 + +`--public` でアップロードした trace.zip は Playwright Trace Viewer で直接開ける。 + +```bash +uv run python scripts/upload_evidence.py reports/.../trace.zip \ + --kind trace --public --parent-folder-id +# → playwright_trace_viewer: https://trace.playwright.dev/?trace=... +``` + +この URL を共有すると、インストール不要でブラウザ上から trace を再生できる。 + +**注意**: `--public` は anyone/read を付与するため、trace 内の機密情報 (Cookie, 入力値) が +公開される。社内限定の場合は private のまま `playwright show-trace` をローカルで使うこと。 + +## 環境変数 + +| 変数 | 用途 | 例 | +|---|---|---| +| `GOOGLE_AUTH_SCRIPTS` | google-auth skill の scripts/ パス | `~/.claude/skills/google-auth/scripts` | +| `PWK_DRIVE_FOLDER` | デフォルトの Drive アップロード先 (将来対応予定) | `1ABCxyz...` | + +## トラブルシュート + +| 症状 | 原因 | 対策 | +|---|---|---| +| `google_auth スキルが見つかりません` | google-auth skill 未インストール | `GOOGLE_AUTH_SCRIPTS` env を設定、または `/ndf:google-auth` で認証セットアップ | +| `HttpError 403: insufficient permissions` | drive.file スコープ不足 | `/ndf:google-auth` で再認証 (`drive.file` スコープ指定) | +| `HttpError 404: File not found` | FOLDER_ID が間違っている / アクセス権なし | Drive で共有フォルダ ID を確認 | +| `resumable upload failed` | ファイルサイズが大きい / ネットワーク不安定 | 再試行。動画は mp4 (H.264) で容量を抑える | +| pytest 後に自動アップロードされない | `--pwk-drive-folder` 未指定 | CLI 引数を確認 | + +## 関連 Skill + +- `/ndf:playwright-authoring` — スクリプト作成と実行 (前段) +- `/ndf:playwright-planning` — テスト計画 +- `/ndf:playwright-kit-ops` — 実行環境の運用 (アップロードスクリプトの配置元) +- `/ndf:google-auth` — Google API OAuth2 認証 +- `/ndf:google-drive` — Google Drive 汎用操作 diff --git a/plugins/ndf-codex/skills/playwright-execution/SKILL.md b/plugins/ndf-codex/skills/playwright-execution/SKILL.md deleted file mode 100644 index f99970cd..00000000 --- a/plugins/ndf-codex/skills/playwright-execution/SKILL.md +++ /dev/null @@ -1,101 +0,0 @@ ---- -name: playwright-execution -description: "Run Playwright E2E tests with evidence and metrics." -when_to_use: "E2E テストの実行 / エビデンス収集 / 動画エビデンス / accessibility チェック / Core Web Vitals 計測が必要なとき。テストスクリプト作成済みであることが前提。Triggers: 'E2E テスト実行', 'テスト実行', '動画エビデンス', 'エビデンス収集', 'テスト証跡', 'a11y テスト', 'accessibility テスト', 'axe-core', 'WCAG', 'Core Web Vitals', 'Web Vitals', 'LCP', 'CLS', 'body_check', 'overlay', '字幕', 'カーソル'" -allowed-tools: - - Read - - Bash(uv *) - - Bash(pytest *) - - Bash(npx *) - - Bash(playwright *) - - Bash(python *) ---- - -# Playwright Execution (テスト実行 + エビデンス収集) - -テストスクリプト作成済みの状態で E2E テストを実行し、エビデンスを収集する。 - -## 前提条件 - -- テストスクリプトが `tests/` に作成済みであること (`/ndf:playwright-script-creation` で作成) -- `scenario.config.yaml` が設定済みであること - -## 大原則 - -**エビデンス動画はデフォルト ON**。全テストで常に動画を取得する。 -明示的にスキップする場合のみ `--pwk-no-video` を指定する。 - -## 実行コマンド - -```bash -./scenario-test/run.sh # 全テスト (動画 ON) -./scenario-test/run.sh -k test_admin # フィルタ -./scenario-test/run.sh --pwk-overlay # 字幕 + カーソル付き動画 -./scenario-test/run.sh --pwk-no-video # 動画のみ OFF -./scenario-test/run.sh --pwk-no-evidence # 全エビデンス OFF (HAR/trace/動画) -``` - -## エビデンス種別 - -| 種別 | デフォルト | OFF フラグ | 説明 | -|---|---|---|---| -| video | **ON** | `--pwk-no-video` | 全テストの動画を取得 | -| trace | ON (retain-on-failure) | `--pwk-no-evidence` | Playwright Trace (DOM + 操作ログ) | -| HAR | ON (minimal) | `--pwk-har-mode none` | ネットワーク通信ログ | -| screenshot | ON (only-on-failure) | `--pwk-no-evidence` | 失敗時スクリーンショット | - -## overlay (赤丸カーソル + 字幕) - -`--pwk-overlay` フラグで全テストの動画にオーバーレイが適用される。 - -API 詳細・使用例は `playwright_kit/overlay.py` を参照。主要関数: `set_caption()`, `flash_click()`, `hide_cursor()`。 - -## 品質計測 - -### accessibility (axe-core) - -`@pytest.mark.page_role` marker が付いたテストで auto_roles にマッチする場合に自動実行。 -設定は `scenario.config.yaml` の `accessibility:` セクションで制御。→ 設定例は `templates/scenario.config.yaml` を参照。 - -### Core Web Vitals - -`@pytest.mark.page_role` marker + auto_roles マッチで LCP/CLS/TTFB/longest_task を自動計測。 -設定は `scenario.config.yaml` の `web_vitals:` セクションで制御。→ 設定例は `templates/scenario.config.yaml` を参照。 - -### body_check (PHP/SSR エラー検出) - -`page.on("response")` で全 HTML レスポンスを監視し、`Fatal error` 等を検出。デフォルト有効。 -`@pytest.mark.no_body_check` で個別 opt-out 可能。→ 設定例は `templates/scenario.config.yaml` の `body_check:` セクションを参照。 - -## 成果物 - -``` -reports// -├── report.md # テスト結果サマリ -├── / -│ ├── video.mp4 # テスト動画 (デフォルト ON) -│ ├── trace.zip # Playwright Trace -│ ├── request.har # ネットワーク通信ログ -│ ├── body_check.jsonl # body_check 違反詳細 -│ └── screenshot-*.png # スクリーンショット -``` - -## CLI options - -| option | 役割 | -|---|---| -| `--pwk-config ` | `scenario.config.yaml` のパス | -| `--pwk-out-dir ` | 成果物出力先 (default: `reports//`) | -| `--pwk-no-video` | 動画収集を OFF (デフォルトは ON) | -| `--pwk-no-evidence` | HAR / trace / video の収集を全て OFF | -| `--pwk-har-mode {minimal,full,none}` | HAR 録画モード (default: minimal) | -| `--pwk-overlay` | overlay (赤丸カーソル + 字幕) を ON | - -## 関連 Skill - -- `/ndf:playwright-script-creation` — テストスクリプト作成 (実行の前段) -- `/ndf:playwright-report` — Markdown レポート生成 -- `/ndf:playwright-kit-ops` — スクリプト実行 (init_project / スキャン) -- `/ndf:playwright-browser-connect` — ブラウザ接続構成 (local / CDP remote) -- `/ndf:playwright-evidence-drive` — エビデンス Google Drive 保管 -- `/ndf:playwright-scenario-test` — 全機能統括 diff --git a/plugins/ndf-codex/skills/playwright-kit-ops/SKILL.md b/plugins/ndf-codex/skills/playwright-kit-ops/SKILL.md index 327c1b09..39cbeb03 100644 --- a/plugins/ndf-codex/skills/playwright-kit-ops/SKILL.md +++ b/plugins/ndf-codex/skills/playwright-kit-ops/SKILL.md @@ -111,9 +111,6 @@ playwright_kit Python パッケージ本体・templates・tests はこの skill ## 関連 Skill -- `/ndf:playwright-test-planning` — テスト計画 (方法論 + チェックリスト) -- `/ndf:playwright-script-creation` — テストスクリプト作成 -- `/ndf:playwright-execution` — テスト実行 + エビデンス収集 (video/trace/overlay/quality) -- `/ndf:playwright-browser-connect` — ブラウザ接続構成 (local / CDP remote) -- `/ndf:playwright-report` — レポート生成 -- `/ndf:playwright-scenario-test` — 全機能統括 +- `/ndf:playwright-planning` — テスト計画 (方法論 + チェックリスト + ワークフロー全体像) +- `/ndf:playwright-authoring` — スクリプト作成と実行 (テストコード / エビデンス / ブラウザ接続) +- `/ndf:playwright-evidence` — 証跡とレポート (report.md / Google Drive 保管) diff --git a/plugins/ndf-codex/skills/playwright-kit-ops/playwright_kit/fixtures/__init__.py b/plugins/ndf-codex/skills/playwright-kit-ops/playwright_kit/fixtures/__init__.py index b9eb5000..dc5e6685 100644 --- a/plugins/ndf-codex/skills/playwright-kit-ops/playwright_kit/fixtures/__init__.py +++ b/plugins/ndf-codex/skills/playwright-kit-ops/playwright_kit/fixtures/__init__.py @@ -1,4 +1,4 @@ -"""playwright-scenario-test pytest fixtures。 +"""playwright_kit pytest fixtures (E2E シナリオテスト)。 利用者は通常の pytest テストを書き、`pwk_config` / `pwk_role_` 等の fixture をパラメタ宣言するだけで NDF の機能 (config / 認証 / evidence / diff --git a/plugins/ndf-codex/skills/playwright-kit-ops/playwright_kit/pytest_plugin.py b/plugins/ndf-codex/skills/playwright-kit-ops/playwright_kit/pytest_plugin.py index 81d7dffa..d8e46208 100644 --- a/plugins/ndf-codex/skills/playwright-kit-ops/playwright_kit/pytest_plugin.py +++ b/plugins/ndf-codex/skills/playwright-kit-ops/playwright_kit/pytest_plugin.py @@ -1,4 +1,4 @@ -"""playwright-scenario-test の pytest plugin。 +"""playwright_kit の pytest plugin (E2E シナリオテスト)。 CLI options: - ``--pwk-config ``: scenario.config.yaml を指定 @@ -42,7 +42,7 @@ def pytest_addoption(parser: pytest.Parser) -> None: - group = parser.getgroup("pwk", "playwright-scenario-test (playwright_kit)") + group = parser.getgroup("pwk", "playwright E2E scenario test (playwright_kit)") group.addoption( "--pwk-config", action="store", diff --git a/plugins/ndf-codex/skills/playwright-kit-ops/templates/conftest.py.template b/plugins/ndf-codex/skills/playwright-kit-ops/templates/conftest.py.template index 9ad04d43..c6741398 100644 --- a/plugins/ndf-codex/skills/playwright-kit-ops/templates/conftest.py.template +++ b/plugins/ndf-codex/skills/playwright-kit-ops/templates/conftest.py.template @@ -1,6 +1,6 @@ """利用者プロジェクトの ``tests/conftest.py`` 雛形。 -playwright-scenario-test (playwright_kit) を pytest-playwright 上で使うための +playwright_kit を pytest-playwright 上で使うための 共通設定。plugin (``playwright_kit.pytest_plugin``) は entry-point 経由で auto-load されるため、import や ``pytest_plugins`` 宣言は不要。 @@ -29,7 +29,7 @@ from playwright.sync_api import Browser, BrowserType # scenario.config.yaml の browser.mode に応じてブラウザ接続を切り替える。 # - local: pytest-playwright デフォルト (chromium.launch()) # - cdp-remote: connect_over_cdp() で既存 Chrome に CDP 接続 -# → /ndf:playwright-browser-connect 参照 +# → /ndf:playwright-authoring 参照 @pytest.fixture(scope="session") diff --git a/plugins/ndf-codex/skills/playwright-kit-ops/templates/scenario.config.yaml b/plugins/ndf-codex/skills/playwright-kit-ops/templates/scenario.config.yaml index 6bd08b49..b9f7d6ad 100644 --- a/plugins/ndf-codex/skills/playwright-kit-ops/templates/scenario.config.yaml +++ b/plugins/ndf-codex/skills/playwright-kit-ops/templates/scenario.config.yaml @@ -17,7 +17,7 @@ # cdp-remote: Chrome DevTools Protocol 経由でリモートブラウザに接続 # → Windows / macOS のホスト Chrome を GUI 付きで操作可能 # → ログイン済み Session (Google, AWS, Slack 等) をそのまま再利用 -# → 詳細は /ndf:playwright-browser-connect を参照 +# → 詳細は /ndf:playwright-authoring を参照 browser: mode: local # cdp-remote 時のみ有効。環境変数で切り替え推奨: diff --git a/plugins/ndf-codex/skills/playwright-planning/SKILL.md b/plugins/ndf-codex/skills/playwright-planning/SKILL.md new file mode 100644 index 00000000..73039aa0 --- /dev/null +++ b/plugins/ndf-codex/skills/playwright-planning/SKILL.md @@ -0,0 +1,124 @@ +--- +name: playwright-planning +description: "Plan Playwright E2E tests by judging page role and choosing checklists and test techniques. Use when starting E2E scenario testing, designing test cases, or laying out the whole E2E workflow (テスト計画 / テスト設計 / page role / チェックリスト / シナリオテスト)." +when_to_use: "E2E テスト計画の立案 / page role 分類 / テスト技法の選定 / pytest-playwright ワークフロー全体像の把握が必要なとき。Triggers: 'HTSM', 'ISTQB', 'FEW HICCUPPS', 'ISO 29119', 'テスト観点', 'テスト計画書', 'フル E2E'" +allowed-tools: + - Read + - Bash(python *) +--- + +# E2E テスト計画 (理論ベース) + +HTSM / ISTQB / FEW HICCUPPS に基づいて E2E テストシナリオを計画する。 +本 Skill は E2E ワークフローの入口であり、全体像の提示と計画フェーズの実行を担う。 + +## 大原則 + +1. **再現可能なテストスクリプトを実装してからテストを実施する** +2. **テストスクリプトは ndf plugin 非依存でプロジェクトフォルダに設置する** +3. **テスト実行はエビデンス動画を常に取得する** (オプションで明示的にスキップ可能) + +## 全体ワークフロー + +``` +[1] テスト計画 /ndf:playwright-planning ← 本 Skill + │ 対象 URL → page role 判定 → チェックリスト → テスト技法確定 + ▼ +[2] スクリプト作成と実行 /ndf:playwright-authoring + │ テンプレート → 実装 → 再現可能性レビュー → 実行 + エビデンス収集 + │ ※ スクリプトが完成するまでテスト実行に進まない + ▼ +[3] 証跡とレポート /ndf:playwright-evidence + │ reports//report.md 生成 → Google Drive 保管・共有 + ▼ +[任意] 実行環境の運用 /ndf:playwright-kit-ops + init_project / 単発スキャン / アップロードスクリプト (任意タイミング) +``` + +## クイックスタート + +1. プロジェクト初期化: `/ndf:playwright-kit-ops` で `./scripts/init_project.sh /path/to/your-app` を実行 +2. 設定編集: `scenario-test/scenario.config.yaml` +3. テストスクリプト作成: `scenario-test/tests/test_*.py` (→ `/ndf:playwright-authoring`) +4. テスト実行 (動画デフォルト ON): `./scenario-test/run.sh` +5. 動画スキップ: `./scenario-test/run.sh --pwk-no-video` + +→ `your-app/scenario-test/` は ndf plugin 非依存。単体で完結する。 + +## 計画ワークフロー + +``` +[A] 対象 URL を渡される + │ +[B] page role を判定 → scripts/classify_page_role.py --url + ▼ +[C] 該当チェックリストを開く → docs/checklists/checklist-{role}.md + │ 全項目を「適用」or「不適用 (理由付き)」で判定 + ▼ +[D] 必須テスト技法を確定 → docs/03-test-techniques.md § 11 + ▼ +[E] pytest テストを書く → templates/test_.py.template を起点に + ▼ +[F] スクリプト作成と実行へ → /ndf:playwright-authoring + テスト計画が完了するまでスクリプト作成には進まない。 +``` + +## page role 一覧 + +| role | 説明 | 例 | +|---|---|---| +| lp | ランディングページ | トップ、LP | +| list | 一覧ページ | 商品一覧、記事一覧 | +| item | 詳細ページ | 商品詳細、記事詳細 | +| edit | 編集ページ | プロフィール編集 | +| form | 申込・入力フォーム | 会員登録、問い合わせ | +| search | 検索ページ | サイト内検索 | +| dashboard | ダッシュボード | 管理画面トップ | +| auth | 認証ページ | ログイン、パスワードリセット | +| cart-checkout | カート・決済 | ショッピングカート | +| modal-wizard | モーダル・ウィザード | ステップ型入力 | + +## チェックリスト + +`playwright-planning/docs/checklists/` 配下に role 別チェックリストがある。 +`checklist-common.md` が全 role 共通項目 (accessibility / Core Web Vitals / セキュリティ / i18n) で、 +残りは上表の role 名に対応する `checklist-{role}.md` である。 + +## 方法論ドキュメント + +`playwright-planning/docs/` 配下: + +| ファイル | 内容 | +|---|---| +| `README.md` | 方法論ドキュメント全体の索引と利用フロー | +| `01-methodology.md` | HTSM / FEW HICCUPPS / ISO 29119-3 の概要 | +| `02-page-roles.md` | page role 分類の詳細定義 | +| `03-test-techniques.md` | テスト技法 (EP/BVA/Decision Table/Pairwise) + role 必須マッピング | +| `04-playwright-mapping.md` | Playwright API → role / 観点 マッピング | +| `05-bug-report.md` | 不具合報告書の仕様 (ISO 29119-3 + FEW HICCUPPS oracle) | +| `06-pytest-playwright.md` | pytest-playwright fixture / CLI option と NDF 拡張の対応 | + +## 補助スクリプト + +スクリプトの実行は `/ndf:playwright-kit-ops` を参照。計画フェーズで使う主なコマンド: + +```bash +# page role を自動推定 +python scripts/classify_page_role.py --url + +# Playwright codegen で操作を記録 → テストコードに変換 +python scripts/record_scenario.py +``` + +> 上記は `playwright-kit-ops/` ディレクトリ内での実行を想定。 + +## 用語集 + +用語 (accessibility, web vitals, LCP, CLS, TTFB, HAR, trace, overlay, body_check, page role, pwk) は +`docs/README.md` の「用語」節、および playwright_kit ランタイムの README (`playwright-kit-ops/templates/runtime-README.md`) を参照。 + +## 関連 Skill + +- `/ndf:playwright-authoring` — スクリプト作成と実行 (次フェーズ) +- `/ndf:playwright-evidence` — 証跡とレポート +- `/ndf:playwright-kit-ops` — 実行環境の運用 (init_project / スキャン / アップロード) diff --git a/plugins/ndf-codex/skills/playwright-test-planning/docs/01-methodology.md b/plugins/ndf-codex/skills/playwright-planning/docs/01-methodology.md similarity index 100% rename from plugins/ndf-codex/skills/playwright-test-planning/docs/01-methodology.md rename to plugins/ndf-codex/skills/playwright-planning/docs/01-methodology.md diff --git a/plugins/ndf-codex/skills/playwright-test-planning/docs/02-page-roles.md b/plugins/ndf-codex/skills/playwright-planning/docs/02-page-roles.md similarity index 100% rename from plugins/ndf-codex/skills/playwright-test-planning/docs/02-page-roles.md rename to plugins/ndf-codex/skills/playwright-planning/docs/02-page-roles.md diff --git a/plugins/ndf-codex/skills/playwright-test-planning/docs/03-test-techniques.md b/plugins/ndf-codex/skills/playwright-planning/docs/03-test-techniques.md similarity index 100% rename from plugins/ndf-codex/skills/playwright-test-planning/docs/03-test-techniques.md rename to plugins/ndf-codex/skills/playwright-planning/docs/03-test-techniques.md diff --git a/plugins/ndf-codex/skills/playwright-test-planning/docs/04-playwright-mapping.md b/plugins/ndf-codex/skills/playwright-planning/docs/04-playwright-mapping.md similarity index 100% rename from plugins/ndf-codex/skills/playwright-test-planning/docs/04-playwright-mapping.md rename to plugins/ndf-codex/skills/playwright-planning/docs/04-playwright-mapping.md diff --git a/plugins/ndf-codex/skills/playwright-test-planning/docs/05-bug-report.md b/plugins/ndf-codex/skills/playwright-planning/docs/05-bug-report.md similarity index 100% rename from plugins/ndf-codex/skills/playwright-test-planning/docs/05-bug-report.md rename to plugins/ndf-codex/skills/playwright-planning/docs/05-bug-report.md diff --git a/plugins/ndf-codex/skills/playwright-test-planning/docs/06-pytest-playwright.md b/plugins/ndf-codex/skills/playwright-planning/docs/06-pytest-playwright.md similarity index 100% rename from plugins/ndf-codex/skills/playwright-test-planning/docs/06-pytest-playwright.md rename to plugins/ndf-codex/skills/playwright-planning/docs/06-pytest-playwright.md diff --git a/plugins/ndf-codex/skills/playwright-test-planning/docs/README.md b/plugins/ndf-codex/skills/playwright-planning/docs/README.md similarity index 100% rename from plugins/ndf-codex/skills/playwright-test-planning/docs/README.md rename to plugins/ndf-codex/skills/playwright-planning/docs/README.md diff --git a/plugins/ndf-codex/skills/playwright-test-planning/docs/checklists/checklist-auth.md b/plugins/ndf-codex/skills/playwright-planning/docs/checklists/checklist-auth.md similarity index 100% rename from plugins/ndf-codex/skills/playwright-test-planning/docs/checklists/checklist-auth.md rename to plugins/ndf-codex/skills/playwright-planning/docs/checklists/checklist-auth.md diff --git a/plugins/ndf-codex/skills/playwright-test-planning/docs/checklists/checklist-cart-checkout.md b/plugins/ndf-codex/skills/playwright-planning/docs/checklists/checklist-cart-checkout.md similarity index 100% rename from plugins/ndf-codex/skills/playwright-test-planning/docs/checklists/checklist-cart-checkout.md rename to plugins/ndf-codex/skills/playwright-planning/docs/checklists/checklist-cart-checkout.md diff --git a/plugins/ndf-codex/skills/playwright-test-planning/docs/checklists/checklist-common.md b/plugins/ndf-codex/skills/playwright-planning/docs/checklists/checklist-common.md similarity index 100% rename from plugins/ndf-codex/skills/playwright-test-planning/docs/checklists/checklist-common.md rename to plugins/ndf-codex/skills/playwright-planning/docs/checklists/checklist-common.md diff --git a/plugins/ndf-codex/skills/playwright-test-planning/docs/checklists/checklist-dashboard.md b/plugins/ndf-codex/skills/playwright-planning/docs/checklists/checklist-dashboard.md similarity index 100% rename from plugins/ndf-codex/skills/playwright-test-planning/docs/checklists/checklist-dashboard.md rename to plugins/ndf-codex/skills/playwright-planning/docs/checklists/checklist-dashboard.md diff --git a/plugins/ndf-codex/skills/playwright-test-planning/docs/checklists/checklist-edit.md b/plugins/ndf-codex/skills/playwright-planning/docs/checklists/checklist-edit.md similarity index 100% rename from plugins/ndf-codex/skills/playwright-test-planning/docs/checklists/checklist-edit.md rename to plugins/ndf-codex/skills/playwright-planning/docs/checklists/checklist-edit.md diff --git a/plugins/ndf-codex/skills/playwright-test-planning/docs/checklists/checklist-form.md b/plugins/ndf-codex/skills/playwright-planning/docs/checklists/checklist-form.md similarity index 100% rename from plugins/ndf-codex/skills/playwright-test-planning/docs/checklists/checklist-form.md rename to plugins/ndf-codex/skills/playwright-planning/docs/checklists/checklist-form.md diff --git a/plugins/ndf-codex/skills/playwright-test-planning/docs/checklists/checklist-item.md b/plugins/ndf-codex/skills/playwright-planning/docs/checklists/checklist-item.md similarity index 100% rename from plugins/ndf-codex/skills/playwright-test-planning/docs/checklists/checklist-item.md rename to plugins/ndf-codex/skills/playwright-planning/docs/checklists/checklist-item.md diff --git a/plugins/ndf-codex/skills/playwright-test-planning/docs/checklists/checklist-list.md b/plugins/ndf-codex/skills/playwright-planning/docs/checklists/checklist-list.md similarity index 100% rename from plugins/ndf-codex/skills/playwright-test-planning/docs/checklists/checklist-list.md rename to plugins/ndf-codex/skills/playwright-planning/docs/checklists/checklist-list.md diff --git a/plugins/ndf-codex/skills/playwright-test-planning/docs/checklists/checklist-lp.md b/plugins/ndf-codex/skills/playwright-planning/docs/checklists/checklist-lp.md similarity index 100% rename from plugins/ndf-codex/skills/playwright-test-planning/docs/checklists/checklist-lp.md rename to plugins/ndf-codex/skills/playwright-planning/docs/checklists/checklist-lp.md diff --git a/plugins/ndf-codex/skills/playwright-test-planning/docs/checklists/checklist-modal-wizard.md b/plugins/ndf-codex/skills/playwright-planning/docs/checklists/checklist-modal-wizard.md similarity index 100% rename from plugins/ndf-codex/skills/playwright-test-planning/docs/checklists/checklist-modal-wizard.md rename to plugins/ndf-codex/skills/playwright-planning/docs/checklists/checklist-modal-wizard.md diff --git a/plugins/ndf-codex/skills/playwright-test-planning/docs/checklists/checklist-search.md b/plugins/ndf-codex/skills/playwright-planning/docs/checklists/checklist-search.md similarity index 100% rename from plugins/ndf-codex/skills/playwright-test-planning/docs/checklists/checklist-search.md rename to plugins/ndf-codex/skills/playwright-planning/docs/checklists/checklist-search.md diff --git a/plugins/ndf-codex/skills/playwright-report/SKILL.md b/plugins/ndf-codex/skills/playwright-report/SKILL.md deleted file mode 100644 index 2f8897a7..00000000 --- a/plugins/ndf-codex/skills/playwright-report/SKILL.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -name: playwright-report -description: "Generate Playwright test result reports." -when_to_use: "テストレポートの生成 / テスト結果の共有が必要なとき。Triggers: 'テストレポート', 'report.md', 'テスト結果', 'テスト報告書', 'レポート生成', 'テスト結果まとめ'" -allowed-tools: - - Read - - Bash(uv *) - - Bash(pytest *) - - Bash(python *) ---- - -# Playwright Report (レポート生成) - -テスト実行後に **Markdown レポート** を自動生成する。 - -## 自動生成 - -`pytest_terminal_summary` hook で `reports//report.md` が自動生成される。特別な設定は不要。 - -```bash -./scenario-test/run.sh -# → reports//report.md が生成される -``` - -## レポート内容 - -| セクション | 内容 | -|---|---| -| サマリ表 | nodeid, role, page_role, 結果, 実行時間, エラー数 | -| 失敗詳細 | FAIL/ERROR のテストごとの詳細情報 | -| body_check 違反 | PHP/SSR エラー検出の詳細 (URL, パターン, スニペット) | -| エビデンスリンク | video, trace, HAR, screenshot へのパス | - -## レポート設定 - -`scenario.config.yaml` の `report` セクション: - -```yaml -report: - title: "シナリオ E2E テスト 実施報告書" - test_plan_link: "./test-plan.md" - phase_labels: {} -``` - -## Google Drive での共有 - -レポート + エビデンスを Drive にアップロードしてチーム共有する場合は -`/ndf:playwright-evidence-drive` を参照。 - -## 関連 Skill - -- `/ndf:playwright-execution` — テスト実行 + エビデンス収集 -- `/ndf:playwright-evidence-drive` — エビデンス Google Drive 保管・共有 -- `/ndf:playwright-kit-ops` — エビデンスアップロードツール (スクリプト群) -- `/ndf:playwright-scenario-test` — 全機能を統括したフルワークフロー diff --git a/plugins/ndf-codex/skills/playwright-script-creation/SKILL.md b/plugins/ndf-codex/skills/playwright-script-creation/SKILL.md deleted file mode 100644 index a42c0a8f..00000000 --- a/plugins/ndf-codex/skills/playwright-script-creation/SKILL.md +++ /dev/null @@ -1,108 +0,0 @@ ---- -name: playwright-script-creation -description: "Create reproducible Playwright E2E test scripts." -when_to_use: "E2E テストスクリプトの作成 / テストコードの実装 / テストテンプレートからのスクリプト生成が必要なとき。Triggers: 'テストスクリプト作成', 'テストコード作成', 'テスト実装', 'テストを書く', 'シナリオ作成', 'codegen', 'テンプレートからテスト', 'playwright codegen'" -allowed-tools: - - Read - - Edit - - Write - - Bash(uv *) - - Bash(playwright *) - - Bash(python *) ---- - -# Playwright Script Creation (テストスクリプト作成) - -再現可能なテストスクリプトを作成し、レビューを経てからテスト実行に進む。 - -## 大原則 - -**テストスクリプトを実装してからテストを実施する。** -スクリプトが完成・レビューを経るまで `/ndf:playwright-execution` に進まない。 - -## 前提条件 - -- テスト計画が完了していること (`/ndf:playwright-test-planning` で計画済み) -- `init_project.sh` でプロジェクトが初期化済みであること (`/ndf:playwright-kit-ops`) - -## ワークフロー - -``` -[A] テスト計画の確認 (チェックリスト / page role / テスト技法) - │ -[B] テンプレート選択 - │ tests/ 配下の test_*.py.template を起点にする - ▼ -[C] テストコード実装 - │ playwright codegen で操作を記録 → テスト関数に組み込む - │ または手動で expect() ベースの assertion を書く - ▼ -[D] 再現可能性レビュー (下記チェックリスト) - │ -[E] テスト実行へ → /ndf:playwright-execution -``` - -## テンプレート一覧 - -`init_project.sh` で以下のテンプレートが `tests/` に配置済み: - -| テンプレート | page role | 内容 | -|---|---|---| -| `test_auth.py` | auth | ログイン / ログアウトフロー | -| `test_list.py` | list | 一覧ページネーション / ソート | -| `test_form.py` | form | 入力 → 送信 → 結果検証 | -| `test_dashboard.py` | dashboard | KPI / リンク遷移 | - -## テストコードの書き方 - -### テンプレートを起点にする - -各 page role のテンプレートが `templates/test_*.py.template` に用意されている。 -`init_project.sh` 実行時に `tests/` へコピーされるので、プロジェクト固有の URL やセレクタを書き換えて使う。 - -→ コード例: `templates/test_form.py.template`, `templates/test_auth.py.template` 等を参照 - -### playwright codegen での操作記録 - -`uv run playwright codegen ` で操作を記録し、生成コードをテスト関数にコピーする。 -コピー後に `@pytest.mark.page_role()`, `@pytest.mark.role()`, `expect()` assertion, `pwk_config.base_url` を追加する。 - -### overlay 付きテスト - -overlay API (`set_caption`, `flash_click`) の使用例は `playwright_kit/overlay.py` を参照。 - -## fixture / marker 一覧 - -fixture / marker の完全な一覧は `playwright_kit/pytest_plugin.py` の `_PWK_MARKERS` 定義と `playwright_kit/fixtures/` 配下の各モジュールを参照。 - -主な fixture: `pwk_config`, `pwk_role_`, `pwk_evidence`, `pwk_accessibility_scan()`, `pwk_web_vitals_measure()` -主な marker: `@pytest.mark.page_role()`, `@pytest.mark.role()`, `@pytest.mark.phase()`, `@pytest.mark.priority()`, `@pytest.mark.no_body_check` - -## 再現可能性レビューチェックリスト - -スクリプト完成後、以下を全項目確認してからテスト実行に進む: - -- [ ] **再現可能性**: 同じ環境で同じ結果が得られるか (ランダム値・タイムスタンプに依存していないか) -- [ ] **テストデータ独立性**: 外部の状態に依存せず、テスト単体で成立するか -- [ ] **marker 付与**: `@pytest.mark.page_role()` が全テスト関数に付与されているか -- [ ] **role marker**: 認証が必要なテストに `@pytest.mark.role()` + `pwk_role_` fixture があるか -- [ ] **assertion 網羅性**: 正常系 + 少なくとも 1 つの異常系 (バリデーション等) が含まれるか -- [ ] **URL 構築**: ハードコードされた URL ではなく `pwk_config.base_url` を使用しているか -- [ ] **wait 戦略**: `wait_until="domcontentloaded"` 等の明示的な待機指定があるか -- [ ] **ndf plugin 非依存**: `scenario-test/` ディレクトリ単体で実行可能か - -## ndf plugin 非依存 - -`init_project.sh` で埋め込まれた `scenario-test/` は: -- `playwright_kit/` パッケージ本体を含む -- `pyproject.toml` で pytest11 entry-point を定義 -- `run.sh` でワンコマンド実行可能 - -→ ndf plugin 未インストール環境でも `./scenario-test/run.sh` で動作する。 - -## 関連 Skill - -- `/ndf:playwright-test-planning` — テスト計画 (前段) -- `/ndf:playwright-execution` — テスト実行 + エビデンス収集 (後段) -- `/ndf:playwright-kit-ops` — init_project / codegen 等のツール群 -- `/ndf:playwright-scenario-test` — 全機能統括 diff --git a/plugins/ndf-codex/skills/playwright-test-planning/SKILL.md b/plugins/ndf-codex/skills/playwright-test-planning/SKILL.md deleted file mode 100644 index a0810adc..00000000 --- a/plugins/ndf-codex/skills/playwright-test-planning/SKILL.md +++ /dev/null @@ -1,97 +0,0 @@ ---- -name: playwright-test-planning -description: "Plan E2E tests and classify page roles." -when_to_use: "E2E テストの計画立案 / page role 分類 / テスト技法の選定 / チェックリスト活用が必要なとき。Triggers: 'テスト計画', 'テスト計画立案', 'page role', 'HTSM', 'ISTQB', 'FEW HICCUPPS', 'チェックリスト', 'テスト技法', 'テスト設計'" -allowed-tools: - - Read - - Bash(python *) ---- - -# E2E テスト計画 (理論ベース) - -HTSM / ISTQB / FEW HICCUPPS に基づいて E2E テストシナリオを計画する。 - -## 計画ワークフロー - -``` -[A] 対象 URL を渡される - │ -[B] page role を判定 → scripts/classify_page_role.py --url - ▼ -[C] 該当チェックリストを開く → docs/checklists/checklist-{role}.md - │ 全項目を「適用」or「不適用 (理由付き)」で判定 - ▼ -[D] 必須テスト技法を確定 → docs/03-test-techniques.md § 11 - ▼ -[E] pytest テストを書く → templates/test_.py.template を起点に - ▼ -[F] スクリプト作成へ → /ndf:playwright-script-creation - テスト計画が確定したら、テストスクリプトの作成に進む。 - テスト計画が完了するまでスクリプト作成には進まない。 -``` - -## page role 一覧 - -| role | 説明 | 例 | -|---|---|---| -| lp | ランディングページ | トップ、LP | -| list | 一覧ページ | 商品一覧、記事一覧 | -| item | 詳細ページ | 商品詳細、記事詳細 | -| edit | 編集ページ | プロフィール編集 | -| form | 申込・入力フォーム | 会員登録、問い合わせ | -| search | 検索ページ | サイト内検索 | -| dashboard | ダッシュボード | 管理画面トップ | -| auth | 認証ページ | ログイン、パスワードリセット | -| cart-checkout | カート・決済 | ショッピングカート | -| modal-wizard | モーダル・ウィザード | ステップ型入力 | - -## チェックリスト - -`playwright-test-planning/docs/checklists/` 配下に role 別チェックリストがある: - -``` -docs/checklists/ -├── checklist-common.md # 全 role 共通項目 -├── checklist-lp.md -├── checklist-list.md -├── checklist-item.md -├── checklist-edit.md -├── checklist-form.md -├── checklist-search.md -├── checklist-dashboard.md -├── checklist-auth.md -├── checklist-cart-checkout.md -└── checklist-modal-wizard.md -``` - -## 方法論ドキュメント - -`playwright-test-planning/docs/` 配下: - -| ファイル | 内容 | -|---|---| -| `01-methodology.md` | HTSM / FEW HICCUPPS / ISO 29119-3 の概要 | -| `02-page-roles.md` | page role 分類の詳細定義 | -| `03-test-techniques.md` | テスト技法 (EP/BVA/Decision Table/Pairwise) + role 必須マッピング | -| `04-playwright-mapping.md` | Playwright API → role / 観点 マッピング | -| `05-bug-report.md` | 不具合報告書の仕様 (ISO 29119-3 + FEW HICCUPPS oracle) | - -## 補助スクリプト - -スクリプトの実行は `/ndf:playwright-kit-ops` skill を参照。主なコマンド: - -```bash -# page role を自動推定 (playwright-kit-ops/scripts/ 配下) -python scripts/classify_page_role.py --url - -# Playwright codegen で操作を記録 → テストコードに変換 -python scripts/record_scenario.py -``` - -> 上記は `playwright-kit-ops/` ディレクトリ内での実行を想定。詳細は `/ndf:playwright-kit-ops` を参照。 - -## 関連 Skill - -- `/ndf:playwright-script-creation` — テストスクリプト作成 (次のフェーズ) -- `/ndf:playwright-execution` — テスト実行 + エビデンス収集 -- `/ndf:playwright-scenario-test` — 全機能を統括したフルワークフロー diff --git a/plugins/ndf-kiro/skills/browser-test/SKILL.md b/plugins/ndf-kiro/skills/browser-test/SKILL.md deleted file mode 100644 index 97eb0c82..00000000 --- a/plugins/ndf-kiro/skills/browser-test/SKILL.md +++ /dev/null @@ -1,159 +0,0 @@ ---- -name: browser-test -description: "Run browser smoke tests for web apps." -argument-hint: "[url]" -disable-model-invocation: true -allowed-tools: - - Bash - - mcp__playwright__browser_navigate - - mcp__playwright__browser_snapshot - - mcp__playwright__browser_click - - mcp__playwright__browser_fill_form - - mcp__playwright__browser_take_screenshot - - mcp__playwright__browser_type - - mcp__playwright__browser_evaluate - - mcp__playwright__browser_console_messages - - mcp__playwright__browser_wait_for - - mcp__playwright__browser_tabs - - mcp__playwright__browser_navigate_back - - mcp__playwright__browser_close - - mcp__playwright__browser_resize - - mcp__playwright__browser_handle_dialog - - mcp__playwright__browser_press_key - - mcp__playwright__browser_hover - - mcp__playwright__browser_select_option - - mcp__playwright__browser_drag - - mcp__playwright__browser_network_requests - - mcp__playwright__browser_file_upload - - mcp__playwright__browser_install - - mcp__chrome-devtools__navigate_page - - mcp__chrome-devtools__take_snapshot - - mcp__chrome-devtools__click - - mcp__chrome-devtools__fill_form - - mcp__chrome-devtools__take_screenshot - - mcp__chrome-devtools__type - - mcp__chrome-devtools__evaluate_script - - mcp__chrome-devtools__list_console_messages - - mcp__chrome-devtools__wait_for - - mcp__chrome-devtools__list_pages - - mcp__chrome-devtools__new_page - - mcp__chrome-devtools__select_page - - mcp__chrome-devtools__close_page - - mcp__chrome-devtools__navigate_page_history - - mcp__chrome-devtools__resize_page - - mcp__chrome-devtools__handle_dialog - - mcp__chrome-devtools__hover - - mcp__chrome-devtools__drag - - mcp__chrome-devtools__list_network_requests - - mcp__chrome-devtools__get_network_request - - mcp__chrome-devtools__upload_file - - mcp__chrome-devtools__emulate_network - - mcp__chrome-devtools__emulate_cpu - - mcp__chrome-devtools__performance_start_trace - - mcp__chrome-devtools__performance_stop_trace - - mcp__chrome-devtools__performance_analyze_insight ---- - -# ブラウザ動作確認コマンド - -現在のブランチで実装されたWeb機能をブラウザで動作確認する。Playwright MCP または Chrome DevTools MCP を利用可能な方を自動選択する。 - -## 前提条件(重要) - -このコマンドは以下のいずれかのMCPサーバが必要: - -- **Playwright MCP**: 自動的にブラウザを起動(要Playwrightインストール) -- **Chrome DevTools MCP**: 既に開いているChromeを操作(Chromeをデバッグモードで起動しておく必要あり) - -どちらも利用できない環境では、手動確認手順を案内する。 - -## 使用方法 - -``` -/ndf:browser-test # 現在のブランチの実装を確認 -/ndf:browser-test http://localhost:8080 # 特定URLを確認 -``` - -## MCPの使い分け - -### Playwright MCP -- 自動的にブラウザを起動 -- 複数ブラウザ対応 (Chromium/Firefox/WebKit) -- 利用可能なら第一選択 - -### Chrome DevTools MCP -- 既に開いているChromeブラウザを操作 -- Chrome デバッグモードでの起動が必要: - - macOS: `/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222` - - Windows: `chrome.exe --remote-debugging-port=9222` - - Linux: `google-chrome --remote-debugging-port=9222` -- DevTools統合でパフォーマンス分析可能 - -## 処理フロー - -### 1. アプリケーション起動確認 - -プロジェクトで使っている起動方法に応じて確認: - -```bash -# Docker Compose の場合 -docker compose ps - -# ネイティブ起動の場合 -curl -fsS http://localhost:/health || echo "NOT RUNNING" -``` - -起動していない場合は、起動手順をユーザーに案内。 - -### 2. ブラウザアクセスと認証 - -- 指定URL(または `/` )にアクセス -- 必要に応じてログイン(資格情報はプロジェクト固有、事前に取得しておく) - -### 3. 機能画面への遷移 - -実装された機能に応じて適切な画面に遷移する。 - -### 4. 動作確認 - -必要に応じて以下の操作を実行: - -- フォーム入力 -- ボタンクリック -- データ表示の確認 -- コンソールエラーの確認 -- ネットワークリクエストの確認 -- スクリーンショット(明示的に指示された場合のみ) - -### 5. 結果報告 - -```markdown -## 動作確認結果 - -### 実施項目 -- [x] ログイン -- [x] 機能画面表示 -- [x] フォーム送信 -- [x] 結果表示 - -### 確認事項 -- コンソールエラー: なし -- ネットワークエラー: なし -- 期待結果との一致: ok - -### 気になる点 -- ...(あれば) -``` - -## 注意事項 - -- **事前にアプリケーション起動が必要** -- **ログイン情報**: プロジェクトの `.env.example` / README 等から確認。機密情報として扱う -- **スクリーンショット**: 必要な場合のみ明示的に指示されたときに取得 -- **Chrome DevTools使用時**: Chromeをデバッグモードで起動しておく必要あり -- **MCP未インストール環境**: 手動での確認手順を案内する - -## 関連 - -- `/ndf:review-branch` — 変更差分のコードレビュー -- `/ndf:pr-tests` — PR Test Plan の自動実行 diff --git a/plugins/ndf-kiro/skills/issue-plan-strategy/SKILL.md b/plugins/ndf-kiro/skills/issue-plan-strategy/SKILL.md index fdae1ecb..add1e621 100644 --- a/plugins/ndf-kiro/skills/issue-plan-strategy/SKILL.md +++ b/plugins/ndf-kiro/skills/issue-plan-strategy/SKILL.md @@ -251,7 +251,7 @@ release ブランチへの merge が一通り進んだ段階で: - PR 間の API / 型 / スキーマ整合 - 設定値の重複・矛盾 - migration の順序依存 - - E2E シナリオ (`/ndf:playwright-scenario-test` の活用) + - E2E シナリオ (`/ndf:playwright-planning` の活用) - ここで **新たに** 個別 PR 範囲のバグが見つかった場合は、**release PR にコメントせず**、該当の個別 PR (既に merge 済みなら修正差分を載せた新しい修正 PR を release 配下に作成) 側に指摘を書き込み、修正ループを回す。この場合レビュー対象は **修正差分** であり新規 PR でレビューできる(元の差分がそもそも cross-review 未実施だったケースは扱いが異なるため Step 8 のフォールバック参照) - release PR には integration 観点の指摘のみ残す @@ -355,4 +355,4 @@ git checkout release/ - `/ndf:cherry-pick-pr` — 検証ブランチへの cherry-pick PR - `/ndf:review` / `/ndf:review-branch` / `/ndf:cross-review` — レビュー - `/ndf:fix` / `/ndf:resolve-pr-comments` — コメント対応 -- `/ndf:playwright-scenario-test` — release ブランチでの E2E 結合テスト +- `/ndf:playwright-planning` — release ブランチでの E2E 結合テスト diff --git a/plugins/ndf-kiro/skills/playwright-authoring/SKILL.md b/plugins/ndf-kiro/skills/playwright-authoring/SKILL.md new file mode 100644 index 00000000..32754982 --- /dev/null +++ b/plugins/ndf-kiro/skills/playwright-authoring/SKILL.md @@ -0,0 +1,250 @@ +--- +name: playwright-authoring +description: "Create reproducible Playwright test scripts and run them with evidence, or check a page over browser MCP. Use when writing E2E test code, running E2E tests, doing a browser smoke check, or connecting to a remote Chrome over CDP (テストスクリプト作成 / テスト実行 / ブラウザ動作確認 / CDP 接続)." +when_to_use: "テストコード実装 / エビデンス動画・trace 収集 / accessibility・Core Web Vitals 計測 / ブラウザ接続先の変更が必要なとき。Triggers: 'playwright codegen', 'pwk_evidence', 'axe-core', 'WCAG', 'LCP', 'CLS', 'body_check', 'overlay', 'connectOverCDP', 'host.docker.internal', 'remote debugging'" +argument-hint: "[url]" +allowed-tools: + - Read + - Edit + - Write + - Bash + - mcp__playwright__browser_navigate + - mcp__playwright__browser_snapshot + - mcp__playwright__browser_click + - mcp__playwright__browser_fill_form + - mcp__playwright__browser_take_screenshot + - mcp__playwright__browser_type + - mcp__playwright__browser_evaluate + - mcp__playwright__browser_console_messages + - mcp__playwright__browser_wait_for + - mcp__playwright__browser_tabs + - mcp__playwright__browser_navigate_back + - mcp__playwright__browser_close + - mcp__playwright__browser_resize + - mcp__playwright__browser_handle_dialog + - mcp__playwright__browser_press_key + - mcp__playwright__browser_hover + - mcp__playwright__browser_select_option + - mcp__playwright__browser_drag + - mcp__playwright__browser_network_requests + - mcp__playwright__browser_file_upload + - mcp__playwright__browser_install + - mcp__chrome-devtools__navigate_page + - mcp__chrome-devtools__take_snapshot + - mcp__chrome-devtools__click + - mcp__chrome-devtools__fill_form + - mcp__chrome-devtools__take_screenshot + - mcp__chrome-devtools__type + - mcp__chrome-devtools__evaluate_script + - mcp__chrome-devtools__list_console_messages + - mcp__chrome-devtools__wait_for + - mcp__chrome-devtools__list_pages + - mcp__chrome-devtools__new_page + - mcp__chrome-devtools__select_page + - mcp__chrome-devtools__close_page + - mcp__chrome-devtools__navigate_page_history + - mcp__chrome-devtools__resize_page + - mcp__chrome-devtools__handle_dialog + - mcp__chrome-devtools__hover + - mcp__chrome-devtools__drag + - mcp__chrome-devtools__list_network_requests + - mcp__chrome-devtools__get_network_request + - mcp__chrome-devtools__upload_file + - mcp__chrome-devtools__emulate_network + - mcp__chrome-devtools__emulate_cpu + - mcp__chrome-devtools__performance_start_trace + - mcp__chrome-devtools__performance_stop_trace + - mcp__chrome-devtools__performance_analyze_insight +--- + +# Playwright スクリプト作成と実行 + +再現可能なテストスクリプトを作成し、レビューを経てから実行してエビデンスを収集する。 +スクリプトを介さない単発のブラウザ動作確認は「MCP でのブラウザ動作確認」節で行う。 + +## 大原則 + +1. **テストスクリプトを実装してからテストを実施する。** レビューを通るまで実行フェーズに進まない +2. **エビデンス動画はデフォルト ON。** 明示的にスキップする場合のみ `--pwk-no-video` を指定する +3. **`scenario-test/` は ndf plugin 非依存。** プラグイン未インストール環境でも単体で動く + +## 前提条件 + +- テスト計画が完了していること (`/ndf:playwright-planning`) +- `init_project.sh` でプロジェクトが初期化済みであること (`/ndf:playwright-kit-ops`) +- `scenario.config.yaml` が設定済みであること + +## ワークフロー + +``` +[A] テスト計画の確認 (チェックリスト / page role / テスト技法) + ▼ +[B] テンプレート選択 tests/ 配下の test_*.py を起点にする + ▼ +[C] テストコード実装 codegen で記録 → expect() ベースの assertion を追加 + ▼ +[D] 再現可能性レビュー 下記チェックリストを全項目確認 + ▼ +[E] テスト実行 + エビデンス収集 ./scenario-test/run.sh + ▼ +[F] レポートと証跡へ → /ndf:playwright-evidence +``` + +## テストスクリプト作成 + +### テンプレートを起点にする + +`init_project.sh` で以下のテンプレートが `tests/` に配置済み。プロジェクト固有の URL やセレクタを書き換えて使う。 + +| テンプレート | page role | 内容 | +|---|---|---| +| `test_auth.py` | auth | ログイン / ログアウトフロー | +| `test_list.py` | list | 一覧ページネーション / ソート | +| `test_form.py` | form | 入力 → 送信 → 結果検証 | +| `test_dashboard.py` | dashboard | KPI / リンク遷移 | + +→ コード例は `playwright-kit-ops/templates/test_*.py.template` を参照。 + +### playwright codegen での操作記録 + +`uv run playwright codegen ` で操作を記録し、生成コードをテスト関数にコピーする。 +コピー後に `@pytest.mark.page_role()`, `@pytest.mark.role()`, `expect()` assertion, `pwk_config.base_url` を追加する。 + +### fixture / marker + +完全な一覧は `playwright_kit/pytest_plugin.py` の `_PWK_MARKERS` 定義と `playwright_kit/fixtures/` 配下を参照。 + +- 主な fixture: `pwk_config`, `pwk_role_`, `pwk_evidence`, `pwk_accessibility_scan()`, `pwk_web_vitals_measure()` +- 主な marker: `@pytest.mark.page_role()`, `@pytest.mark.role()`, `@pytest.mark.phase()`, `@pytest.mark.priority()`, `@pytest.mark.no_body_check` + +overlay API (`set_caption`, `flash_click`, `hide_cursor`) の使用例は `playwright_kit/overlay.py` を参照。 + +### 再現可能性レビューチェックリスト + +スクリプト完成後、以下を全項目確認してからテスト実行に進む。 + +- [ ] **再現可能性**: 同じ環境で同じ結果が得られるか (ランダム値・タイムスタンプに依存していないか) +- [ ] **テストデータ独立性**: 外部の状態に依存せず、テスト単体で成立するか +- [ ] **marker 付与**: `@pytest.mark.page_role()` が全テスト関数に付与されているか +- [ ] **role marker**: 認証が必要なテストに `@pytest.mark.role()` + `pwk_role_` fixture があるか +- [ ] **assertion 網羅性**: 正常系 + 少なくとも 1 つの異常系 (バリデーション等) が含まれるか +- [ ] **URL 構築**: ハードコードされた URL ではなく `pwk_config.base_url` を使用しているか +- [ ] **wait 戦略**: `wait_until="domcontentloaded"` 等の明示的な待機指定があるか +- [ ] **ndf plugin 非依存**: `scenario-test/` ディレクトリ単体で実行可能か + +## テスト実行 + +```bash +./scenario-test/run.sh # 全テスト (動画 ON) +./scenario-test/run.sh -k test_admin # フィルタ +./scenario-test/run.sh --pwk-overlay # 字幕 + カーソル付き動画 +./scenario-test/run.sh --pwk-no-video # 動画のみ OFF +./scenario-test/run.sh --pwk-no-evidence # 全エビデンス OFF (HAR/trace/動画) +``` + +### CLI options + +| option | 役割 | +|---|---| +| `--pwk-config ` | `scenario.config.yaml` のパス | +| `--pwk-out-dir ` | 成果物出力先 (default: `reports//`) | +| `--pwk-no-video` | 動画収集を OFF (デフォルトは ON) | +| `--pwk-no-evidence` | HAR / trace / video の収集を全て OFF | +| `--pwk-har-mode {minimal,full,none}` | HAR 録画モード (default: minimal) | +| `--pwk-overlay` | overlay (赤丸カーソル + 字幕) を ON | +| `--pwk-drive-folder=` | 実行後に Drive へ自動アップロード (→ `/ndf:playwright-evidence`) | + +### エビデンス種別と成果物 + +| 種別 | デフォルト | OFF フラグ | 説明 | +|---|---|---|---| +| video | **ON** | `--pwk-no-video` | 全テストの動画を取得 | +| trace | ON (retain-on-failure) | `--pwk-no-evidence` | Playwright Trace (DOM + 操作ログ) | +| HAR | ON (minimal) | `--pwk-har-mode none` | ネットワーク通信ログ | +| screenshot | ON (only-on-failure) | `--pwk-no-evidence` | 失敗時スクリーンショット | + +``` +reports// +├── report.md # テスト結果サマリ +├── / +│ ├── video.mp4 # テスト動画 (デフォルト ON) +│ ├── trace.zip # Playwright Trace +│ ├── request.har # ネットワーク通信ログ +│ ├── body_check.jsonl # body_check 違反詳細 +│ └── screenshot-*.png # スクリーンショット +``` + +### 品質計測 + +いずれも `scenario.config.yaml` で制御する。設定例は `playwright-kit-ops/templates/scenario.config.yaml` を参照。 + +| 計測 | 発動条件 | 設定セクション | +|---|---|---| +| accessibility (axe-core) | `@pytest.mark.page_role` が auto_roles にマッチ | `accessibility:` | +| Core Web Vitals (LCP/CLS/TTFB/longest_task) | 同上 | `web_vitals:` | +| body_check (PHP/SSR エラー検出) | 常時有効。`@pytest.mark.no_body_check` で opt-out | `body_check:` | + +body_check は `page.on("response")` で全 HTML レスポンスを監視し、`Fatal error` 等を検出する。 + +## ブラウザ接続 + +| モード | scenario.config.yaml | 接続先 | 用途 | +|---|---|---|---| +| `local` | `browser.mode: local` | コンテナ内 Chromium | CI / ヘッドレス実行 (デフォルト) | +| `cdp-remote` | `browser.mode: cdp-remote` | リモート Chrome (CDP) | GUI 操作・ログイン済み Session 再利用 | + +```yaml +browser: + # local: playwright install chromium でインストールしたローカルブラウザ (デフォルト) + # cdp-remote: Chrome DevTools Protocol 経由でリモートブラウザに接続 + mode: local + # cdp-remote 時のみ有効 + cdp_endpoint: ${CDP_ENDPOINT:-http://localhost:9222} +``` + +WSL2 / macOS / Linux ホストの Chrome へ CDP 接続する手順、`scripts/start-host-chrome.sh` によるホスト +Chrome の起動、`conftest.py` への統合、ネットワーク到達性の確保、トラブルシュートは +[references/browser-connection.md](references/browser-connection.md) を参照。 + +## MCP でのブラウザ動作確認 + +テストスクリプトを書かずに、現在のブランチの実装をブラウザで確認する手順。Playwright MCP または +Chrome DevTools MCP の利用可能な方を自動選択する。どちらも使えない環境では手動確認手順を案内する。 + +``` +/ndf:playwright-authoring # 現在のブランチの実装を確認 +/ndf:playwright-authoring http://localhost:8080 # 特定 URL を確認 +``` + +| MCP | 特徴 | 前提 | +|---|---|---| +| Playwright MCP | 自動でブラウザを起動。Chromium/Firefox/WebKit 対応。利用可能なら第一選択 | Playwright インストール | +| Chrome DevTools MCP | 既に開いている Chrome を操作。DevTools 統合でパフォーマンス分析可能 | Chrome をデバッグモードで起動 (`--remote-debugging-port=9222`) | + +### 手順 + +1. **アプリケーション起動確認**: `docker compose ps` や `curl -fsS http://localhost:/health` で確認する。起動していなければ起動手順を案内する +2. **アクセスと認証**: 指定 URL (または `/`) にアクセスし、必要ならログインする。資格情報はプロジェクト固有で、`.env.example` / README から確認し機密情報として扱う +3. **機能画面への遷移**: 実装された機能に応じた画面へ遷移する +4. **動作確認**: フォーム入力・ボタンクリック・データ表示・コンソールエラー・ネットワークリクエストを確認する。スクリーンショットは明示的に指示されたときのみ取得する +5. **結果報告**: 実施項目 / 確認事項 (コンソールエラー・ネットワークエラー・期待結果との一致) / 気になる点 を Markdown で報告する + +継続的に回すべき確認は、この手順で得た操作列をテストスクリプトへ落とし込む (本 Skill の前半)。 + +## ndf plugin 非依存 + +`init_project.sh` で埋め込まれた `scenario-test/` は `playwright_kit/` パッケージ本体を含み、 +`pyproject.toml` で pytest11 entry-point を定義し、`run.sh` でワンコマンド実行できる。 +→ ndf plugin 未インストール環境でも `./scenario-test/run.sh` で動作する。 + +## 関連 Skill + +- `/ndf:playwright-planning` — テスト計画 (前段) +- `/ndf:playwright-evidence` — 証跡とレポート (後段) +- `/ndf:playwright-kit-ops` — 実行環境の運用 (init_project / codegen / スキャン) +- `/ndf:docker-container-access` — Docker コンテナアクセス一般 +- `/ndf:review-branch` — 変更差分のコードレビュー +- `/ndf:pr-tests` — PR Test Plan の自動実行 + +> `playwright-planning` / `playwright-evidence` / `playwright-kit-ops` は Codex 公開セットに同梱される。 +> Claude Code / Kiro CLI では `plugins/ndf-shared/skills/` を直接参照する。 diff --git a/plugins/ndf-kiro/skills/playwright-authoring/references/browser-connection.md b/plugins/ndf-kiro/skills/playwright-authoring/references/browser-connection.md new file mode 100644 index 00000000..29e7d4de --- /dev/null +++ b/plugins/ndf-kiro/skills/playwright-authoring/references/browser-connection.md @@ -0,0 +1,326 @@ +# ブラウザ接続構成 (local / CDP remote) + +E2E テスト実行時のブラウザ接続先を構成する手順。概要と設定項目は `SKILL.md` の「ブラウザ接続」節を参照。 + +## Chrome 起動フラグ + +CDP 接続に使う Chrome は次のフラグで起動する。OS ごとの差はバイナリパスだけである。 + +| フラグ | 役割 | +|---|---| +| `--remote-debugging-port=9222` | CDP エンドポイントを 9222 で公開 | +| `--remote-allow-origins=*` | CDP WebSocket の Host ヘッダ検証を無効化し、コンテナ等リモートからの接続を許可 (Chrome 106+) | +| `--user-data-dir=/tmp/chrome-debug` | 専用プロファイルで起動し、通常の Chrome と共存させる。任意のパスでよい | +| `--disable-features=DialMediaRouteProvider` | DIAL (Cast) 探索を無効化し、CDP ログのノイズと不要な通信を抑制 | +| `--remote-debugging-address=0.0.0.0` | 全インターフェースで listen する。loopback bind でコンテナから届かない場合のみ付与 | + +既存プロファイルのログイン済み Session をそのまま使う場合は、**全 Chrome プロセスを終了してから** +`--user-data-dir` を外して起動する (デフォルトプロファイルを使用)。 + +> **Security**: `--remote-allow-origins=*` と `--remote-debugging-address=0.0.0.0` は信頼できるネットワーク内でのみ使用する。ファイアウォールでポート 9222 へのアクセスを制限することを推奨。 + +## パターン 1: ローカルコンテナ Chromium (デフォルト) + +設定不要。`run.sh` 初回実行時に `playwright install chromium` が自動実行される。 + +```yaml +browser: + mode: local +``` + +## パターン 2: Windows ホスト Chrome (WSL2 + Docker → CDP) + +``` +Docker container (playwright) + ↓ http://host.docker.internal:9222 +Docker Desktop (WSL2 backend) → Windows host → localhost:9222 + ↓ +Chrome (--remote-debugging-port=9222 --remote-allow-origins=*) +``` + +**Step 1: Windows Chrome をリモートデバッグモードで起動** + +```powershell +& "C:\Program Files\Google\Chrome\Application\chrome.exe" ` + --remote-debugging-port=9222 ` + --remote-allow-origins=* ` + --user-data-dir="C:\tmp\chrome-debug" +``` + +> Chrome はデフォルトで `127.0.0.1` にバインドするため、`--remote-allow-origins=*` だけでは WSL2/Docker から接続できない場合がある。その場合は後述の「ネットワーク別接続ガイド」で到達性を確保する。 + +**Step 2: WSL2 .wslconfig を NAT mode にする** + +```ini +# %USERPROFILE%\.wslconfig +[wsl2] +networkingMode=NAT +``` + +**Step 3: scenario.config.yaml** + +Docker Desktop (WSL2 backend) は `host.docker.internal` を標準サポートしている。 + +```yaml +browser: + mode: cdp-remote + cdp_endpoint: ${CDP_ENDPOINT:-http://host.docker.internal:9222} +``` + +> **Docker Desktop を使わず WSL2 から直接実行する場合**: `host.docker.internal` は Docker Desktop 固有の DNS 名のため使えない。Windows ホストの IP を直接指定する。 +> ```bash +> export CDP_ENDPOINT="http://$(grep nameserver /etc/resolv.conf | awk '{print $2}'):9222" +> ``` + +## パターン 3: macOS ホスト Chrome (Docker → CDP) + +``` +Docker container (playwright) + ↓ http://host.docker.internal:9222 +macOS host → localhost:9222 + ↓ +Chrome (--remote-debugging-port=9222 --remote-allow-origins=*) +``` + +**Step 1: ホスト側で Chrome を起動** + +```bash +"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \ + --remote-debugging-port=9222 \ + --user-data-dir=/tmp/chrome-debug \ + --remote-allow-origins=* \ + --disable-features=DialMediaRouteProvider +``` + +> **Note**: 上記は macOS Docker Desktop で動作実績のあるコマンド。macOS Docker Desktop は `host.docker.internal` がホストの loopback (127.0.0.1) バインドのサービスに到達できるため、`--remote-debugging-address=0.0.0.0` は不要で、全インターフェース公開によるセキュリティ低下も避けられる。Linux / WSL2 ホストで loopback bind が問題になる場合のみ `0.0.0.0` を付与する。 + +**Step 2: scenario.config.yaml** + +`--remote-allow-origins=*` で Host ヘッダ検証を無効化しているため、WSL2 と異なり **proxy 不要**。 + +```yaml +browser: + mode: cdp-remote + cdp_endpoint: ${CDP_ENDPOINT:-http://host.docker.internal:9222} +``` + +**Step 3 (任意): コンテナからホスト Chrome を起動する** → 次節。 + +## コンテナからホスト Chrome を起動する (SSH 経由) + +### なぜ直接は起動できないのか + +Docker コンテナはホストとプロセス空間が分離されているため、**コンテナ内のプロセスがホスト上に直接プロセスを生成することはできない**。 +特に macOS / Windows の Docker Desktop はコンテナを LinuxKit VM 内で実行するため、`nsenter` やホスト PID namespace を使う Linux 系の回避策も VM 止まりでホストには届かない。 + +したがって「コンテナからホストの Chrome を起動する」には、**ホスト側に起動を受け付ける口** が必要になる。最も導入が容易でスクリプト化しやすいのは **SSH** (macOS の「リモートログイン」= sshd) を使う方法。 + +``` +Docker container ──ssh──▶ host.docker.internal:22 (macOS sshd) + └─▶ Google Chrome --remote-debugging-port=9222 ... (バックグラウンド起動) +Docker container ──CDP──▶ host.docker.internal:9222 (起動後に接続) +``` + +### ホスト側の準備 (一度だけ) + +1. **リモートログインを有効化**: システム設定 > 一般 > 共有 > 「リモートログイン」を ON (CLI: `sudo systemsetup -setremotelogin on`) +2. **SSH 鍵を登録** (パスワードレス実行のため): コンテナ側の公開鍵をホストの `~/.ssh/authorized_keys` に追加 +3. ログインユーザーは **コンソールにログイン中の本人** であること。macOS では GUI アプリ (Chrome) は WindowServer に接続するため、コンソールセッションの所有者として起動する必要がある + +### スクリプト + +`scripts/start-host-chrome.sh` をコンテナ内から実行する。冪等で、既に CDP が起動済みなら何もしない。 + +```bash +# コンテナ内 +HOST_SSH_USER= ./scripts/start-host-chrome.sh +``` + +| 変数 | デフォルト | 説明 | +|---|---|---| +| `HOST_SSH_USER` | (必須) | ホスト (mac) のログインユーザー名 | +| `HOST_SSH_HOST` | `host.docker.internal` | SSH 接続先ホスト | +| `CDP_PORT` | `9222` | リモートデバッグポート | +| `CDP_BIND_ADDRESS` | (空=loopback) | Chrome の listen address。空なら Chrome 既定の loopback bind (macOS Docker Desktop はこれで動作・実証済み)。Linux/WSL2 等で到達できない場合のみ `0.0.0.0` 等を指定 | +| `CHROME_USER_DATA_DIR` | `/tmp/chrome-debug` | 起動プロファイル。空にするとデフォルトプロファイル (ログイン済み Session) を使用 | +| `CHROME_BIN` | `/Applications/Google Chrome.app/Contents/MacOS/Google Chrome` | Chrome バイナリパス | +| `MANUAL_WAIT` | `120` | 手動フォールバック時の起動待ち秒。`0` で待たず即終了 | + +動作: + +1. `http://host.docker.internal:9222/json/version` に疎通すれば **起動済み** とみなし即終了 +2. 未起動なら SSH (`BatchMode=yes`) でホストに接続し、Chrome をバックグラウンド (`nohup ... &`) で起動 +3. CDP エンドポイントが応答するまで最大 30 秒ポーリングして待機 + +### SSH が使えない場合のフォールバック + +`HOST_SSH_USER` 未設定 / コンテナに `ssh` クライアントが無い / SSH 接続・実行に失敗 (鍵未登録・リモートログイン無効・到達不可) のいずれかで、スクリプトは **自動で手動フォールバックに切り替わる**。 + +フォールバック時は、ホスト側で実行すべき起動コマンドをそのまま画面に出力し、`MANUAL_WAIT` 秒 (既定 120s) のあいだ CDP の起動をポーリングして待機する。利用者はその間にホストのターミナルへコマンドを貼り付けて実行すればよい。CI など人手が介在しない環境では `MANUAL_WAIT=0` を指定すれば、案内を出して即座に非ゼロ終了する。 + +> **Note (SSH を使わない代替手段)**: ホスト側に常駐ランチャ (launchd エージェントや FIFO 監視スクリプト、簡易 HTTP エンドポイント等) を置き、コンテナからネットワーク経由でトリガする方法もある。ただし SSH 方式が最も追加実装が少なく確実。X11 forwarding (XQuartz + socat) は「コンテナ内 GUI をホスト画面に表示する」用途であり、本件には不要。 + +> **Note (Linux ホストの場合)**: ホストで sshd が動いていれば同じスクリプトが使える。`CHROME_BIN=google-chrome`、`HOST_SSH_HOST` をホスト IP (`172.17.0.1` 等) に設定する。GUI セッションへの接続には `DISPLAY` 等の追加考慮が必要。 + +## conftest.py への統合 + +`browser.mode: cdp-remote` の場合、pytest-playwright の通常のブラウザ起動をバイパスし、 +`connectOverCDP()` で既存 Chrome に接続する fixture を有効化する必要がある。 + +`scenario-test/conftest.py` に以下を追加する。 + +```python +import pytest +from playwright.sync_api import Browser, BrowserType + +@pytest.fixture(scope="session") +def browser( + browser_type: BrowserType, + browser_type_launch_args: dict, + pwk_config, +) -> Browser: + """browser.mode に応じてブラウザ接続を切り替える。 + + - local: pytest-playwright デフォルト (chromium.launch()) + - cdp-remote: chromium.connect_over_cdp(endpoint) + """ + browser_cfg = pwk_config.browser + # slow_mo: browser_type_launch_args が優先、なければ config の slow_mo_ms + _slow_mo = browser_type_launch_args.get( + "slow_mo", pwk_config.playwright.slow_mo_ms or None + ) + if browser_cfg.mode == "cdp-remote": + if browser_type.name != "chromium": + pytest.fail( + f"cdp-remote モードは Chromium 専用です (現在: {browser_type.name})。" + "--browser chromium を指定するか、browser.mode を local に変更してください。" + ) + browser = browser_type.connect_over_cdp( + browser_cfg.cdp_endpoint, + slow_mo=_slow_mo, + ) + yield browser + # CDP 接続の場合、close() は接続を切断 (disconnect) するだけで、 + # リモートブラウザ自体は終了しない。 + browser.close() + else: + launch_args = {**browser_type_launch_args} + launch_args.setdefault("headless", pwk_config.playwright.headless) + if _slow_mo is not None: + launch_args.setdefault("slow_mo", _slow_mo) + browser = browser_type.launch(**launch_args) + yield browser + browser.close() +``` + +### CDP モードでの既存セッション再利用 + +`browser.new_context()` は新規コンテキストを作成するため、既存のログイン Session は引き継がれない。 +`cdp-remote` モードでは、テンプレートの `conftest.py` が `context` / `page` fixture を自動的にオーバーライドし、 +CDP 接続先の既存コンテキスト (ログイン済み Session) を返す。標準のテストコードは無変更で既存セッションを利用できる。 + +```python +@pytest.fixture(scope="session") +def context(browser, pwk_config, _cdp_default_context): + """cdp-remote: 既存コンテキスト / local: 新規コンテキスト""" + if pwk_config.browser.mode == "cdp-remote" and _cdp_default_context is not None: + yield _cdp_default_context + else: + ctx = browser.new_context() + yield ctx + ctx.close() + +@pytest.fixture(scope="session") +def page(context, pwk_config): + """cdp-remote: 既存ページ / local: 新規ページ""" + if pwk_config.browser.mode == "cdp-remote" and context.pages: + yield context.pages[0] + else: + pg = context.new_page() + yield pg + pg.close() +``` + +## run.sh での利用 + +`cdp-remote` モード時は `playwright install chromium` が不要。`run.sh` は初回セットアップで +`playwright install` を実行するが、接続先がリモートの場合はスキップして問題ない。 + +```bash +# エンドポイントの疎通確認 +curl -s http://host.docker.internal:9222/json/version | python3 -m json.tool +``` + +## ネットワーク別接続ガイド + +Chrome はデフォルトで `127.0.0.1` にバインドするため、同一ホストからしか CDP エンドポイントにアクセスできない。 +Docker コンテナや WSL2 からリモート接続する場合は、次のいずれかで到達性を確保する。 + +### 方法 1: `--remote-debugging-address=0.0.0.0` (推奨) + +Chrome 起動時に全インターフェースでリッスンさせる。最もシンプル。フラグの詳細は冒頭の表を参照。 + +### 方法 2: socat によるポートフォワード (Linux) + +Chrome を `127.0.0.1` バインドのまま維持し、socat でリモートからのアクセスを中継する。 + +```bash +socat TCP-LISTEN:9222,bind=0.0.0.0,reuseaddr,fork TCP:127.0.0.1:9222 +``` + +### 方法 3: netsh portproxy (Windows → WSL2) + +```powershell +# 管理者権限の PowerShell で実行 +netsh interface portproxy add v4tov4 ` + listenaddress=0.0.0.0 listenport=9222 ` + connectaddress=127.0.0.1 connectport=9222 + +netsh interface portproxy show all +netsh interface portproxy delete v4tov4 listenaddress=0.0.0.0 listenport=9222 +``` + +### 接続先の早見表 + +| 実行環境 | Chrome の場所 | 推奨方法 | CDP エンドポイント | +|---|---|---|---| +| ローカル (同一ホスト) | 同一ホスト | 設定不要 | `http://localhost:9222` | +| Docker → ホスト (macOS) | macOS ホスト | 方法 1 | `http://host.docker.internal:9222` | +| Docker → ホスト (Linux) | Linux ホスト | 方法 1 or 2 | `http://host.docker.internal:9222` or `http://172.17.0.1:9222` | +| Docker (WSL2) → Windows | Windows ホスト | 方法 1 or 3 | `http://host.docker.internal:9222` | +| WSL2 → Windows | Windows ホスト | 方法 1 or 3 | `http://$(grep nameserver /etc/resolv.conf \| awk '{print $2}'):9222` | + +## トラブルシュート + +### 共通 + +| 症状 | 原因 | 対策 | +|---|---|---| +| `connect_over_cdp` で接続拒否 | Chrome が起動していない / ポートが違う | `curl http:///json/version` で確認 | +| WebSocket handshake 失敗 | Host ヘッダ不一致 | Chrome 起動時に `--remote-allow-origins=*` を付与 | +| ページ操作が異常に遅い | VPN / DNS 解決の遅延 | `extra_hosts` で IP 直指定 | + +### Windows (WSL2) 固有 + +| 症状 | 原因 | 対策 | +|---|---|---| +| `host.docker.internal` 解決不能 | Docker Desktop 未使用 or 古いバージョン | Docker Desktop を使用するか、WSL2 直接の場合は Windows ホスト IP を直接指定 | +| IPv6 でバインドされる | WSL2 が IPv6 優先 | listen address に `0.0.0.0` を明示 | +| `netsh portproxy` で接続ループ | portproxy の自己参照 | `--remote-allow-origins=*` を使い proxy を廃止 | +| mirrored mode で動かない | mirrored は localhost 共有だが CDP の WS 接続でポート競合 | NAT mode に戻す | + +### macOS 固有 + +| 症状 | 原因 | 対策 | +|---|---|---| +| `host.docker.internal` 解決不能 | Docker Desktop が古い / Linux Docker | `--add-host=host.docker.internal:host-gateway` を指定 | +| ファイアウォールでブロック | macOS のアプリファイアウォール | システム設定 > ネットワーク > ファイアウォール で Chrome を許可 | +| SSH 起動で Chrome が表示されない / WindowServer エラー | コンソール非ログインユーザーで SSH した | コンソールにログイン中の本人ユーザーで SSH する | +| `start-host-chrome.sh` が SSH で認証失敗 | リモートログイン未有効 / 鍵未登録 | `sudo systemsetup -setremotelogin on` と `authorized_keys` 登録を確認 | + +## CDP 接続のメリット + +- **GUI Chrome をそのまま操作可能** — OBS 録画可、人間と AI の協調操作が可能 +- **ログイン済み Session の再利用** — Google / AWS / Slack 等の MFA 済み Session をそのまま使える +- **ブラウザ拡張機能が有効** — テスト時にも拡張機能の影響を確認可能 +- **AI Agent との相性** — Claude Code / Browser Use / OpenHands がリアルブラウザを操作 diff --git a/plugins/ndf-kiro/skills/playwright-authoring/scripts/start-host-chrome.sh b/plugins/ndf-kiro/skills/playwright-authoring/scripts/start-host-chrome.sh new file mode 100755 index 00000000..8c7b1d08 --- /dev/null +++ b/plugins/ndf-kiro/skills/playwright-authoring/scripts/start-host-chrome.sh @@ -0,0 +1,172 @@ +#!/usr/bin/env bash +# コンテナ内から SSH 経由でホスト (macOS / Linux) の Chrome を +# リモートデバッグモードで起動するスクリプト。 +# +# 背景: +# Docker コンテナはホストとプロセス空間が分離されているため、 +# コンテナから直接ホストのプロセスを起動できない。 +# ホストの sshd (macOS: システム設定 > 共有 > リモートログイン) に接続し、 +# 起動コマンドを実行することで間接的にホスト Chrome を起動する。 +# +# SSH が使えない場合 (鍵未登録・リモートログイン無効など) は、 +# ホスト側で手動実行する起動コマンドを案内し、起動されるまで待機する +# フォールバックに切り替わる。 +# +# 前提 (SSH 自動起動を使う場合のみ・ホスト側で一度だけ設定): +# 1) リモートログインを有効化 (macOS: sudo systemsetup -setremotelogin on) +# 2) コンテナの公開鍵を ~/.ssh/authorized_keys に登録 (パスワードレス実行) +# 3) コンソールにログイン中の本人ユーザーで SSH すること +# (GUI アプリは WindowServer 接続のためコンソールセッション所有者が必要) +# +# 使い方 (コンテナ内): +# # SSH 自動起動 +# HOST_SSH_USER= ./scripts/start-host-chrome.sh +# # SSH を使わず手動起動の案内のみ +# ./scripts/start-host-chrome.sh +# +# 環境変数: +# HOST_SSH_USER ホストのログインユーザー名。未設定なら手動フォールバック +# HOST_SSH_HOST SSH 接続先 (default: host.docker.internal) +# CDP_HOST CDP 疎通確認先ホスト (default: HOST_SSH_HOST) +# CDP_PORT リモートデバッグポート (default: 9222) +# CDP_BIND_ADDRESS Chrome の listen address。空 (default) なら付与せず +# Chrome 既定の loopback bind (macOS Docker Desktop は +# host.docker.internal がホスト loopback に到達するため +# これで動作する)。Linux/WSL2 等で loopback bind だと +# コンテナから到達できない場合のみ 0.0.0.0 等を指定する。 +# 0.0.0.0 は全インターフェース公開のためセキュリティ注意。 +# CHROME_USER_DATA_DIR 起動プロファイル (default: /tmp/chrome-debug) +# 空にするとデフォルトプロファイル (ログイン済み Session) を使用 +# CHROME_BIN Chrome バイナリパス +# (default: /Applications/Google Chrome.app/Contents/MacOS/Google Chrome) +# STARTUP_TIMEOUT SSH 起動後の待機タイムアウト秒 (default: 30) +# MANUAL_WAIT 手動フォールバック時の待機秒。0 で待たず即終了 (default: 120) +set -euo pipefail + +HOST_SSH_USER="${HOST_SSH_USER:-}" +HOST_SSH_HOST="${HOST_SSH_HOST:-host.docker.internal}" +CDP_HOST="${CDP_HOST:-$HOST_SSH_HOST}" +CDP_PORT="${CDP_PORT:-9222}" +CDP_BIND_ADDRESS="${CDP_BIND_ADDRESS:-}" +CHROME_USER_DATA_DIR="${CHROME_USER_DATA_DIR-/tmp/chrome-debug}" +CHROME_BIN="${CHROME_BIN:-/Applications/Google Chrome.app/Contents/MacOS/Google Chrome}" +STARTUP_TIMEOUT="${STARTUP_TIMEOUT:-30}" +MANUAL_WAIT="${MANUAL_WAIT:-120}" + +# curl は冪等チェック・起動待機・手動フォールバックの全経路で CDP 疎通確認に +# 使う必須コマンド。無いと終了コード 127 で常に未起動扱いとなり、起動成功時でも +# タイムアウトしてしまうため、ここでフェイルファストする。 +if ! command -v curl >/dev/null 2>&1; then + echo "✗ curl が見つかりません。CDP 疎通確認に必須です。" >&2 + echo " コンテナに curl をインストールしてから再実行してください" >&2 + echo " (例: apt-get install -y curl / apk add curl)。" >&2 + exit 1 +fi + +cdp_up() { + # --max-time でネットワークハング時も待機ループ周期が壊れないようにする + curl -sf --max-time 2 "http://${CDP_HOST}:${CDP_PORT}/json/version" >/dev/null 2>&1 +} + +# --user-data-dir は空文字なら付与しない (デフォルトプロファイル使用) +userdata_arg="" +if [ -n "${CHROME_USER_DATA_DIR}" ]; then + userdata_arg="--user-data-dir='${CHROME_USER_DATA_DIR}'" +fi + +# --remote-debugging-address は CDP_BIND_ADDRESS が空なら付与しない。 +# 既定 (空) では Chrome は loopback (127.0.0.1) のみ listen する。macOS +# Docker Desktop は host.docker.internal がホストの loopback に到達するため +# これで動作する (ユーザー実証済み・0.0.0.0 不要)。 +# Linux/WSL2 等で loopback bind だとコンテナから到達できない場合のみ +# CDP_BIND_ADDRESS=0.0.0.0 等を指定する。0.0.0.0 は CDP を全インターフェース +# へ公開し、CDP は認証なしでブラウザ操作できるためセキュリティに注意すること。 +bind_arg="" +if [ -n "${CDP_BIND_ADDRESS}" ]; then + bind_arg="--remote-debugging-address=${CDP_BIND_ADDRESS} " +fi + +# ホスト側で実行する Chrome 起動コマンド (人間がコピペできる体裁) +host_launch_cmd() { + printf '"%s" --remote-debugging-port=%s %s%s --remote-allow-origins=* --disable-features=DialMediaRouteProvider' \ + "${CHROME_BIN}" "${CDP_PORT}" "${bind_arg}" "${userdata_arg}" +} + +# 手動フォールバック: ホストで実行するコマンドを案内し、起動を待機する +manual_fallback() { + local reason="$1" + echo "" >&2 + echo "──────────────────────────────────────────────────────────────" >&2 + echo "⚠ SSH 自動起動を利用できません (${reason})。" >&2 + echo " ホスト (mac) 側のターミナルで以下を実行してください:" >&2 + echo "" >&2 + echo " $(host_launch_cmd)" >&2 + echo "" >&2 + echo "──────────────────────────────────────────────────────────────" >&2 + + if [ "${MANUAL_WAIT}" -le 0 ]; then + echo "✗ Chrome 未起動のまま終了します (MANUAL_WAIT=0)。" >&2 + exit 1 + fi + + echo "→ ホストでの起動を待機中 (最大 ${MANUAL_WAIT}s, Ctrl-C で中断)..." >&2 + # seq 外部依存も bash 専用 for ((...)) も避け、POSIX 互換 while で待機する + # (最小コンテナ / /bin/sh しかない環境でも動作) + i=0 + while [ "$i" -lt "$MANUAL_WAIT" ]; do + if cdp_up; then + echo "✓ Chrome 起動を検知しました: http://${CDP_HOST}:${CDP_PORT}" + exit 0 + fi + sleep 1 + i=$((i + 1)) + done + echo "✗ 待機タイムアウト。手動起動後に再実行してください。" >&2 + exit 1 +} + +# 1) 既に起動済みなら何もしない (冪等) +if cdp_up; then + echo "✓ Chrome は既に CDP http://${CDP_HOST}:${CDP_PORT} で起動済みです" + exit 0 +fi + +# 2) HOST_SSH_USER 未設定 → 手動フォールバック +if [ -z "${HOST_SSH_USER}" ]; then + manual_fallback "HOST_SSH_USER が未設定" +fi + +# 3) ssh コマンドが無い → 手動フォールバック +if ! command -v ssh >/dev/null 2>&1; then + manual_fallback "コンテナに ssh クライアントが無い" +fi + +# 4) SSH でホストに接続し、Chrome をバックグラウンド起動 +echo "→ ${HOST_SSH_USER}@${HOST_SSH_HOST} で Chrome を起動します..." +# &2 +exit 1 diff --git a/plugins/ndf-shared/manifests/claude-skills.txt b/plugins/ndf-shared/manifests/claude-skills.txt index bb74879b..050f6640 100644 --- a/plugins/ndf-shared/manifests/claude-skills.txt +++ b/plugins/ndf-shared/manifests/claude-skills.txt @@ -21,7 +21,7 @@ deploy review-branch review-pr-comments resolve-pr-comments -browser-test +playwright-authoring codex gemini statusline diff --git a/plugins/ndf-shared/manifests/codex-skills.txt b/plugins/ndf-shared/manifests/codex-skills.txt index 403632f8..56d24ab4 100644 --- a/plugins/ndf-shared/manifests/codex-skills.txt +++ b/plugins/ndf-shared/manifests/codex-skills.txt @@ -14,11 +14,10 @@ markdown-writing merged ndf-policies plan-to-spec -playwright-execution +playwright-authoring +playwright-evidence playwright-kit-ops -playwright-report -playwright-script-creation -playwright-test-planning +playwright-planning pr pr-tests problem-solving diff --git a/plugins/ndf-shared/manifests/kiro-skills.txt b/plugins/ndf-shared/manifests/kiro-skills.txt index b58dc6bd..cc29e885 100644 --- a/plugins/ndf-shared/manifests/kiro-skills.txt +++ b/plugins/ndf-shared/manifests/kiro-skills.txt @@ -21,7 +21,7 @@ deploy review-branch review-pr-comments resolve-pr-comments -browser-test +playwright-authoring codex statusline issue-plan-strategy diff --git a/plugins/ndf-shared/skills/browser-test/SKILL.md b/plugins/ndf-shared/skills/browser-test/SKILL.md deleted file mode 100644 index 97eb0c82..00000000 --- a/plugins/ndf-shared/skills/browser-test/SKILL.md +++ /dev/null @@ -1,159 +0,0 @@ ---- -name: browser-test -description: "Run browser smoke tests for web apps." -argument-hint: "[url]" -disable-model-invocation: true -allowed-tools: - - Bash - - mcp__playwright__browser_navigate - - mcp__playwright__browser_snapshot - - mcp__playwright__browser_click - - mcp__playwright__browser_fill_form - - mcp__playwright__browser_take_screenshot - - mcp__playwright__browser_type - - mcp__playwright__browser_evaluate - - mcp__playwright__browser_console_messages - - mcp__playwright__browser_wait_for - - mcp__playwright__browser_tabs - - mcp__playwright__browser_navigate_back - - mcp__playwright__browser_close - - mcp__playwright__browser_resize - - mcp__playwright__browser_handle_dialog - - mcp__playwright__browser_press_key - - mcp__playwright__browser_hover - - mcp__playwright__browser_select_option - - mcp__playwright__browser_drag - - mcp__playwright__browser_network_requests - - mcp__playwright__browser_file_upload - - mcp__playwright__browser_install - - mcp__chrome-devtools__navigate_page - - mcp__chrome-devtools__take_snapshot - - mcp__chrome-devtools__click - - mcp__chrome-devtools__fill_form - - mcp__chrome-devtools__take_screenshot - - mcp__chrome-devtools__type - - mcp__chrome-devtools__evaluate_script - - mcp__chrome-devtools__list_console_messages - - mcp__chrome-devtools__wait_for - - mcp__chrome-devtools__list_pages - - mcp__chrome-devtools__new_page - - mcp__chrome-devtools__select_page - - mcp__chrome-devtools__close_page - - mcp__chrome-devtools__navigate_page_history - - mcp__chrome-devtools__resize_page - - mcp__chrome-devtools__handle_dialog - - mcp__chrome-devtools__hover - - mcp__chrome-devtools__drag - - mcp__chrome-devtools__list_network_requests - - mcp__chrome-devtools__get_network_request - - mcp__chrome-devtools__upload_file - - mcp__chrome-devtools__emulate_network - - mcp__chrome-devtools__emulate_cpu - - mcp__chrome-devtools__performance_start_trace - - mcp__chrome-devtools__performance_stop_trace - - mcp__chrome-devtools__performance_analyze_insight ---- - -# ブラウザ動作確認コマンド - -現在のブランチで実装されたWeb機能をブラウザで動作確認する。Playwright MCP または Chrome DevTools MCP を利用可能な方を自動選択する。 - -## 前提条件(重要) - -このコマンドは以下のいずれかのMCPサーバが必要: - -- **Playwright MCP**: 自動的にブラウザを起動(要Playwrightインストール) -- **Chrome DevTools MCP**: 既に開いているChromeを操作(Chromeをデバッグモードで起動しておく必要あり) - -どちらも利用できない環境では、手動確認手順を案内する。 - -## 使用方法 - -``` -/ndf:browser-test # 現在のブランチの実装を確認 -/ndf:browser-test http://localhost:8080 # 特定URLを確認 -``` - -## MCPの使い分け - -### Playwright MCP -- 自動的にブラウザを起動 -- 複数ブラウザ対応 (Chromium/Firefox/WebKit) -- 利用可能なら第一選択 - -### Chrome DevTools MCP -- 既に開いているChromeブラウザを操作 -- Chrome デバッグモードでの起動が必要: - - macOS: `/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222` - - Windows: `chrome.exe --remote-debugging-port=9222` - - Linux: `google-chrome --remote-debugging-port=9222` -- DevTools統合でパフォーマンス分析可能 - -## 処理フロー - -### 1. アプリケーション起動確認 - -プロジェクトで使っている起動方法に応じて確認: - -```bash -# Docker Compose の場合 -docker compose ps - -# ネイティブ起動の場合 -curl -fsS http://localhost:/health || echo "NOT RUNNING" -``` - -起動していない場合は、起動手順をユーザーに案内。 - -### 2. ブラウザアクセスと認証 - -- 指定URL(または `/` )にアクセス -- 必要に応じてログイン(資格情報はプロジェクト固有、事前に取得しておく) - -### 3. 機能画面への遷移 - -実装された機能に応じて適切な画面に遷移する。 - -### 4. 動作確認 - -必要に応じて以下の操作を実行: - -- フォーム入力 -- ボタンクリック -- データ表示の確認 -- コンソールエラーの確認 -- ネットワークリクエストの確認 -- スクリーンショット(明示的に指示された場合のみ) - -### 5. 結果報告 - -```markdown -## 動作確認結果 - -### 実施項目 -- [x] ログイン -- [x] 機能画面表示 -- [x] フォーム送信 -- [x] 結果表示 - -### 確認事項 -- コンソールエラー: なし -- ネットワークエラー: なし -- 期待結果との一致: ok - -### 気になる点 -- ...(あれば) -``` - -## 注意事項 - -- **事前にアプリケーション起動が必要** -- **ログイン情報**: プロジェクトの `.env.example` / README 等から確認。機密情報として扱う -- **スクリーンショット**: 必要な場合のみ明示的に指示されたときに取得 -- **Chrome DevTools使用時**: Chromeをデバッグモードで起動しておく必要あり -- **MCP未インストール環境**: 手動での確認手順を案内する - -## 関連 - -- `/ndf:review-branch` — 変更差分のコードレビュー -- `/ndf:pr-tests` — PR Test Plan の自動実行 diff --git a/plugins/ndf-shared/skills/issue-plan-strategy/SKILL.md b/plugins/ndf-shared/skills/issue-plan-strategy/SKILL.md index fdae1ecb..add1e621 100644 --- a/plugins/ndf-shared/skills/issue-plan-strategy/SKILL.md +++ b/plugins/ndf-shared/skills/issue-plan-strategy/SKILL.md @@ -251,7 +251,7 @@ release ブランチへの merge が一通り進んだ段階で: - PR 間の API / 型 / スキーマ整合 - 設定値の重複・矛盾 - migration の順序依存 - - E2E シナリオ (`/ndf:playwright-scenario-test` の活用) + - E2E シナリオ (`/ndf:playwright-planning` の活用) - ここで **新たに** 個別 PR 範囲のバグが見つかった場合は、**release PR にコメントせず**、該当の個別 PR (既に merge 済みなら修正差分を載せた新しい修正 PR を release 配下に作成) 側に指摘を書き込み、修正ループを回す。この場合レビュー対象は **修正差分** であり新規 PR でレビューできる(元の差分がそもそも cross-review 未実施だったケースは扱いが異なるため Step 8 のフォールバック参照) - release PR には integration 観点の指摘のみ残す @@ -355,4 +355,4 @@ git checkout release/ - `/ndf:cherry-pick-pr` — 検証ブランチへの cherry-pick PR - `/ndf:review` / `/ndf:review-branch` / `/ndf:cross-review` — レビュー - `/ndf:fix` / `/ndf:resolve-pr-comments` — コメント対応 -- `/ndf:playwright-scenario-test` — release ブランチでの E2E 結合テスト +- `/ndf:playwright-planning` — release ブランチでの E2E 結合テスト diff --git a/plugins/ndf-shared/skills/playwright-authoring/SKILL.md b/plugins/ndf-shared/skills/playwright-authoring/SKILL.md new file mode 100644 index 00000000..32754982 --- /dev/null +++ b/plugins/ndf-shared/skills/playwright-authoring/SKILL.md @@ -0,0 +1,250 @@ +--- +name: playwright-authoring +description: "Create reproducible Playwright test scripts and run them with evidence, or check a page over browser MCP. Use when writing E2E test code, running E2E tests, doing a browser smoke check, or connecting to a remote Chrome over CDP (テストスクリプト作成 / テスト実行 / ブラウザ動作確認 / CDP 接続)." +when_to_use: "テストコード実装 / エビデンス動画・trace 収集 / accessibility・Core Web Vitals 計測 / ブラウザ接続先の変更が必要なとき。Triggers: 'playwright codegen', 'pwk_evidence', 'axe-core', 'WCAG', 'LCP', 'CLS', 'body_check', 'overlay', 'connectOverCDP', 'host.docker.internal', 'remote debugging'" +argument-hint: "[url]" +allowed-tools: + - Read + - Edit + - Write + - Bash + - mcp__playwright__browser_navigate + - mcp__playwright__browser_snapshot + - mcp__playwright__browser_click + - mcp__playwright__browser_fill_form + - mcp__playwright__browser_take_screenshot + - mcp__playwright__browser_type + - mcp__playwright__browser_evaluate + - mcp__playwright__browser_console_messages + - mcp__playwright__browser_wait_for + - mcp__playwright__browser_tabs + - mcp__playwright__browser_navigate_back + - mcp__playwright__browser_close + - mcp__playwright__browser_resize + - mcp__playwright__browser_handle_dialog + - mcp__playwright__browser_press_key + - mcp__playwright__browser_hover + - mcp__playwright__browser_select_option + - mcp__playwright__browser_drag + - mcp__playwright__browser_network_requests + - mcp__playwright__browser_file_upload + - mcp__playwright__browser_install + - mcp__chrome-devtools__navigate_page + - mcp__chrome-devtools__take_snapshot + - mcp__chrome-devtools__click + - mcp__chrome-devtools__fill_form + - mcp__chrome-devtools__take_screenshot + - mcp__chrome-devtools__type + - mcp__chrome-devtools__evaluate_script + - mcp__chrome-devtools__list_console_messages + - mcp__chrome-devtools__wait_for + - mcp__chrome-devtools__list_pages + - mcp__chrome-devtools__new_page + - mcp__chrome-devtools__select_page + - mcp__chrome-devtools__close_page + - mcp__chrome-devtools__navigate_page_history + - mcp__chrome-devtools__resize_page + - mcp__chrome-devtools__handle_dialog + - mcp__chrome-devtools__hover + - mcp__chrome-devtools__drag + - mcp__chrome-devtools__list_network_requests + - mcp__chrome-devtools__get_network_request + - mcp__chrome-devtools__upload_file + - mcp__chrome-devtools__emulate_network + - mcp__chrome-devtools__emulate_cpu + - mcp__chrome-devtools__performance_start_trace + - mcp__chrome-devtools__performance_stop_trace + - mcp__chrome-devtools__performance_analyze_insight +--- + +# Playwright スクリプト作成と実行 + +再現可能なテストスクリプトを作成し、レビューを経てから実行してエビデンスを収集する。 +スクリプトを介さない単発のブラウザ動作確認は「MCP でのブラウザ動作確認」節で行う。 + +## 大原則 + +1. **テストスクリプトを実装してからテストを実施する。** レビューを通るまで実行フェーズに進まない +2. **エビデンス動画はデフォルト ON。** 明示的にスキップする場合のみ `--pwk-no-video` を指定する +3. **`scenario-test/` は ndf plugin 非依存。** プラグイン未インストール環境でも単体で動く + +## 前提条件 + +- テスト計画が完了していること (`/ndf:playwright-planning`) +- `init_project.sh` でプロジェクトが初期化済みであること (`/ndf:playwright-kit-ops`) +- `scenario.config.yaml` が設定済みであること + +## ワークフロー + +``` +[A] テスト計画の確認 (チェックリスト / page role / テスト技法) + ▼ +[B] テンプレート選択 tests/ 配下の test_*.py を起点にする + ▼ +[C] テストコード実装 codegen で記録 → expect() ベースの assertion を追加 + ▼ +[D] 再現可能性レビュー 下記チェックリストを全項目確認 + ▼ +[E] テスト実行 + エビデンス収集 ./scenario-test/run.sh + ▼ +[F] レポートと証跡へ → /ndf:playwright-evidence +``` + +## テストスクリプト作成 + +### テンプレートを起点にする + +`init_project.sh` で以下のテンプレートが `tests/` に配置済み。プロジェクト固有の URL やセレクタを書き換えて使う。 + +| テンプレート | page role | 内容 | +|---|---|---| +| `test_auth.py` | auth | ログイン / ログアウトフロー | +| `test_list.py` | list | 一覧ページネーション / ソート | +| `test_form.py` | form | 入力 → 送信 → 結果検証 | +| `test_dashboard.py` | dashboard | KPI / リンク遷移 | + +→ コード例は `playwright-kit-ops/templates/test_*.py.template` を参照。 + +### playwright codegen での操作記録 + +`uv run playwright codegen ` で操作を記録し、生成コードをテスト関数にコピーする。 +コピー後に `@pytest.mark.page_role()`, `@pytest.mark.role()`, `expect()` assertion, `pwk_config.base_url` を追加する。 + +### fixture / marker + +完全な一覧は `playwright_kit/pytest_plugin.py` の `_PWK_MARKERS` 定義と `playwright_kit/fixtures/` 配下を参照。 + +- 主な fixture: `pwk_config`, `pwk_role_`, `pwk_evidence`, `pwk_accessibility_scan()`, `pwk_web_vitals_measure()` +- 主な marker: `@pytest.mark.page_role()`, `@pytest.mark.role()`, `@pytest.mark.phase()`, `@pytest.mark.priority()`, `@pytest.mark.no_body_check` + +overlay API (`set_caption`, `flash_click`, `hide_cursor`) の使用例は `playwright_kit/overlay.py` を参照。 + +### 再現可能性レビューチェックリスト + +スクリプト完成後、以下を全項目確認してからテスト実行に進む。 + +- [ ] **再現可能性**: 同じ環境で同じ結果が得られるか (ランダム値・タイムスタンプに依存していないか) +- [ ] **テストデータ独立性**: 外部の状態に依存せず、テスト単体で成立するか +- [ ] **marker 付与**: `@pytest.mark.page_role()` が全テスト関数に付与されているか +- [ ] **role marker**: 認証が必要なテストに `@pytest.mark.role()` + `pwk_role_` fixture があるか +- [ ] **assertion 網羅性**: 正常系 + 少なくとも 1 つの異常系 (バリデーション等) が含まれるか +- [ ] **URL 構築**: ハードコードされた URL ではなく `pwk_config.base_url` を使用しているか +- [ ] **wait 戦略**: `wait_until="domcontentloaded"` 等の明示的な待機指定があるか +- [ ] **ndf plugin 非依存**: `scenario-test/` ディレクトリ単体で実行可能か + +## テスト実行 + +```bash +./scenario-test/run.sh # 全テスト (動画 ON) +./scenario-test/run.sh -k test_admin # フィルタ +./scenario-test/run.sh --pwk-overlay # 字幕 + カーソル付き動画 +./scenario-test/run.sh --pwk-no-video # 動画のみ OFF +./scenario-test/run.sh --pwk-no-evidence # 全エビデンス OFF (HAR/trace/動画) +``` + +### CLI options + +| option | 役割 | +|---|---| +| `--pwk-config ` | `scenario.config.yaml` のパス | +| `--pwk-out-dir ` | 成果物出力先 (default: `reports//`) | +| `--pwk-no-video` | 動画収集を OFF (デフォルトは ON) | +| `--pwk-no-evidence` | HAR / trace / video の収集を全て OFF | +| `--pwk-har-mode {minimal,full,none}` | HAR 録画モード (default: minimal) | +| `--pwk-overlay` | overlay (赤丸カーソル + 字幕) を ON | +| `--pwk-drive-folder=` | 実行後に Drive へ自動アップロード (→ `/ndf:playwright-evidence`) | + +### エビデンス種別と成果物 + +| 種別 | デフォルト | OFF フラグ | 説明 | +|---|---|---|---| +| video | **ON** | `--pwk-no-video` | 全テストの動画を取得 | +| trace | ON (retain-on-failure) | `--pwk-no-evidence` | Playwright Trace (DOM + 操作ログ) | +| HAR | ON (minimal) | `--pwk-har-mode none` | ネットワーク通信ログ | +| screenshot | ON (only-on-failure) | `--pwk-no-evidence` | 失敗時スクリーンショット | + +``` +reports// +├── report.md # テスト結果サマリ +├── / +│ ├── video.mp4 # テスト動画 (デフォルト ON) +│ ├── trace.zip # Playwright Trace +│ ├── request.har # ネットワーク通信ログ +│ ├── body_check.jsonl # body_check 違反詳細 +│ └── screenshot-*.png # スクリーンショット +``` + +### 品質計測 + +いずれも `scenario.config.yaml` で制御する。設定例は `playwright-kit-ops/templates/scenario.config.yaml` を参照。 + +| 計測 | 発動条件 | 設定セクション | +|---|---|---| +| accessibility (axe-core) | `@pytest.mark.page_role` が auto_roles にマッチ | `accessibility:` | +| Core Web Vitals (LCP/CLS/TTFB/longest_task) | 同上 | `web_vitals:` | +| body_check (PHP/SSR エラー検出) | 常時有効。`@pytest.mark.no_body_check` で opt-out | `body_check:` | + +body_check は `page.on("response")` で全 HTML レスポンスを監視し、`Fatal error` 等を検出する。 + +## ブラウザ接続 + +| モード | scenario.config.yaml | 接続先 | 用途 | +|---|---|---|---| +| `local` | `browser.mode: local` | コンテナ内 Chromium | CI / ヘッドレス実行 (デフォルト) | +| `cdp-remote` | `browser.mode: cdp-remote` | リモート Chrome (CDP) | GUI 操作・ログイン済み Session 再利用 | + +```yaml +browser: + # local: playwright install chromium でインストールしたローカルブラウザ (デフォルト) + # cdp-remote: Chrome DevTools Protocol 経由でリモートブラウザに接続 + mode: local + # cdp-remote 時のみ有効 + cdp_endpoint: ${CDP_ENDPOINT:-http://localhost:9222} +``` + +WSL2 / macOS / Linux ホストの Chrome へ CDP 接続する手順、`scripts/start-host-chrome.sh` によるホスト +Chrome の起動、`conftest.py` への統合、ネットワーク到達性の確保、トラブルシュートは +[references/browser-connection.md](references/browser-connection.md) を参照。 + +## MCP でのブラウザ動作確認 + +テストスクリプトを書かずに、現在のブランチの実装をブラウザで確認する手順。Playwright MCP または +Chrome DevTools MCP の利用可能な方を自動選択する。どちらも使えない環境では手動確認手順を案内する。 + +``` +/ndf:playwright-authoring # 現在のブランチの実装を確認 +/ndf:playwright-authoring http://localhost:8080 # 特定 URL を確認 +``` + +| MCP | 特徴 | 前提 | +|---|---|---| +| Playwright MCP | 自動でブラウザを起動。Chromium/Firefox/WebKit 対応。利用可能なら第一選択 | Playwright インストール | +| Chrome DevTools MCP | 既に開いている Chrome を操作。DevTools 統合でパフォーマンス分析可能 | Chrome をデバッグモードで起動 (`--remote-debugging-port=9222`) | + +### 手順 + +1. **アプリケーション起動確認**: `docker compose ps` や `curl -fsS http://localhost:/health` で確認する。起動していなければ起動手順を案内する +2. **アクセスと認証**: 指定 URL (または `/`) にアクセスし、必要ならログインする。資格情報はプロジェクト固有で、`.env.example` / README から確認し機密情報として扱う +3. **機能画面への遷移**: 実装された機能に応じた画面へ遷移する +4. **動作確認**: フォーム入力・ボタンクリック・データ表示・コンソールエラー・ネットワークリクエストを確認する。スクリーンショットは明示的に指示されたときのみ取得する +5. **結果報告**: 実施項目 / 確認事項 (コンソールエラー・ネットワークエラー・期待結果との一致) / 気になる点 を Markdown で報告する + +継続的に回すべき確認は、この手順で得た操作列をテストスクリプトへ落とし込む (本 Skill の前半)。 + +## ndf plugin 非依存 + +`init_project.sh` で埋め込まれた `scenario-test/` は `playwright_kit/` パッケージ本体を含み、 +`pyproject.toml` で pytest11 entry-point を定義し、`run.sh` でワンコマンド実行できる。 +→ ndf plugin 未インストール環境でも `./scenario-test/run.sh` で動作する。 + +## 関連 Skill + +- `/ndf:playwright-planning` — テスト計画 (前段) +- `/ndf:playwright-evidence` — 証跡とレポート (後段) +- `/ndf:playwright-kit-ops` — 実行環境の運用 (init_project / codegen / スキャン) +- `/ndf:docker-container-access` — Docker コンテナアクセス一般 +- `/ndf:review-branch` — 変更差分のコードレビュー +- `/ndf:pr-tests` — PR Test Plan の自動実行 + +> `playwright-planning` / `playwright-evidence` / `playwright-kit-ops` は Codex 公開セットに同梱される。 +> Claude Code / Kiro CLI では `plugins/ndf-shared/skills/` を直接参照する。 diff --git a/plugins/ndf-shared/skills/playwright-authoring/references/browser-connection.md b/plugins/ndf-shared/skills/playwright-authoring/references/browser-connection.md new file mode 100644 index 00000000..29e7d4de --- /dev/null +++ b/plugins/ndf-shared/skills/playwright-authoring/references/browser-connection.md @@ -0,0 +1,326 @@ +# ブラウザ接続構成 (local / CDP remote) + +E2E テスト実行時のブラウザ接続先を構成する手順。概要と設定項目は `SKILL.md` の「ブラウザ接続」節を参照。 + +## Chrome 起動フラグ + +CDP 接続に使う Chrome は次のフラグで起動する。OS ごとの差はバイナリパスだけである。 + +| フラグ | 役割 | +|---|---| +| `--remote-debugging-port=9222` | CDP エンドポイントを 9222 で公開 | +| `--remote-allow-origins=*` | CDP WebSocket の Host ヘッダ検証を無効化し、コンテナ等リモートからの接続を許可 (Chrome 106+) | +| `--user-data-dir=/tmp/chrome-debug` | 専用プロファイルで起動し、通常の Chrome と共存させる。任意のパスでよい | +| `--disable-features=DialMediaRouteProvider` | DIAL (Cast) 探索を無効化し、CDP ログのノイズと不要な通信を抑制 | +| `--remote-debugging-address=0.0.0.0` | 全インターフェースで listen する。loopback bind でコンテナから届かない場合のみ付与 | + +既存プロファイルのログイン済み Session をそのまま使う場合は、**全 Chrome プロセスを終了してから** +`--user-data-dir` を外して起動する (デフォルトプロファイルを使用)。 + +> **Security**: `--remote-allow-origins=*` と `--remote-debugging-address=0.0.0.0` は信頼できるネットワーク内でのみ使用する。ファイアウォールでポート 9222 へのアクセスを制限することを推奨。 + +## パターン 1: ローカルコンテナ Chromium (デフォルト) + +設定不要。`run.sh` 初回実行時に `playwright install chromium` が自動実行される。 + +```yaml +browser: + mode: local +``` + +## パターン 2: Windows ホスト Chrome (WSL2 + Docker → CDP) + +``` +Docker container (playwright) + ↓ http://host.docker.internal:9222 +Docker Desktop (WSL2 backend) → Windows host → localhost:9222 + ↓ +Chrome (--remote-debugging-port=9222 --remote-allow-origins=*) +``` + +**Step 1: Windows Chrome をリモートデバッグモードで起動** + +```powershell +& "C:\Program Files\Google\Chrome\Application\chrome.exe" ` + --remote-debugging-port=9222 ` + --remote-allow-origins=* ` + --user-data-dir="C:\tmp\chrome-debug" +``` + +> Chrome はデフォルトで `127.0.0.1` にバインドするため、`--remote-allow-origins=*` だけでは WSL2/Docker から接続できない場合がある。その場合は後述の「ネットワーク別接続ガイド」で到達性を確保する。 + +**Step 2: WSL2 .wslconfig を NAT mode にする** + +```ini +# %USERPROFILE%\.wslconfig +[wsl2] +networkingMode=NAT +``` + +**Step 3: scenario.config.yaml** + +Docker Desktop (WSL2 backend) は `host.docker.internal` を標準サポートしている。 + +```yaml +browser: + mode: cdp-remote + cdp_endpoint: ${CDP_ENDPOINT:-http://host.docker.internal:9222} +``` + +> **Docker Desktop を使わず WSL2 から直接実行する場合**: `host.docker.internal` は Docker Desktop 固有の DNS 名のため使えない。Windows ホストの IP を直接指定する。 +> ```bash +> export CDP_ENDPOINT="http://$(grep nameserver /etc/resolv.conf | awk '{print $2}'):9222" +> ``` + +## パターン 3: macOS ホスト Chrome (Docker → CDP) + +``` +Docker container (playwright) + ↓ http://host.docker.internal:9222 +macOS host → localhost:9222 + ↓ +Chrome (--remote-debugging-port=9222 --remote-allow-origins=*) +``` + +**Step 1: ホスト側で Chrome を起動** + +```bash +"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \ + --remote-debugging-port=9222 \ + --user-data-dir=/tmp/chrome-debug \ + --remote-allow-origins=* \ + --disable-features=DialMediaRouteProvider +``` + +> **Note**: 上記は macOS Docker Desktop で動作実績のあるコマンド。macOS Docker Desktop は `host.docker.internal` がホストの loopback (127.0.0.1) バインドのサービスに到達できるため、`--remote-debugging-address=0.0.0.0` は不要で、全インターフェース公開によるセキュリティ低下も避けられる。Linux / WSL2 ホストで loopback bind が問題になる場合のみ `0.0.0.0` を付与する。 + +**Step 2: scenario.config.yaml** + +`--remote-allow-origins=*` で Host ヘッダ検証を無効化しているため、WSL2 と異なり **proxy 不要**。 + +```yaml +browser: + mode: cdp-remote + cdp_endpoint: ${CDP_ENDPOINT:-http://host.docker.internal:9222} +``` + +**Step 3 (任意): コンテナからホスト Chrome を起動する** → 次節。 + +## コンテナからホスト Chrome を起動する (SSH 経由) + +### なぜ直接は起動できないのか + +Docker コンテナはホストとプロセス空間が分離されているため、**コンテナ内のプロセスがホスト上に直接プロセスを生成することはできない**。 +特に macOS / Windows の Docker Desktop はコンテナを LinuxKit VM 内で実行するため、`nsenter` やホスト PID namespace を使う Linux 系の回避策も VM 止まりでホストには届かない。 + +したがって「コンテナからホストの Chrome を起動する」には、**ホスト側に起動を受け付ける口** が必要になる。最も導入が容易でスクリプト化しやすいのは **SSH** (macOS の「リモートログイン」= sshd) を使う方法。 + +``` +Docker container ──ssh──▶ host.docker.internal:22 (macOS sshd) + └─▶ Google Chrome --remote-debugging-port=9222 ... (バックグラウンド起動) +Docker container ──CDP──▶ host.docker.internal:9222 (起動後に接続) +``` + +### ホスト側の準備 (一度だけ) + +1. **リモートログインを有効化**: システム設定 > 一般 > 共有 > 「リモートログイン」を ON (CLI: `sudo systemsetup -setremotelogin on`) +2. **SSH 鍵を登録** (パスワードレス実行のため): コンテナ側の公開鍵をホストの `~/.ssh/authorized_keys` に追加 +3. ログインユーザーは **コンソールにログイン中の本人** であること。macOS では GUI アプリ (Chrome) は WindowServer に接続するため、コンソールセッションの所有者として起動する必要がある + +### スクリプト + +`scripts/start-host-chrome.sh` をコンテナ内から実行する。冪等で、既に CDP が起動済みなら何もしない。 + +```bash +# コンテナ内 +HOST_SSH_USER= ./scripts/start-host-chrome.sh +``` + +| 変数 | デフォルト | 説明 | +|---|---|---| +| `HOST_SSH_USER` | (必須) | ホスト (mac) のログインユーザー名 | +| `HOST_SSH_HOST` | `host.docker.internal` | SSH 接続先ホスト | +| `CDP_PORT` | `9222` | リモートデバッグポート | +| `CDP_BIND_ADDRESS` | (空=loopback) | Chrome の listen address。空なら Chrome 既定の loopback bind (macOS Docker Desktop はこれで動作・実証済み)。Linux/WSL2 等で到達できない場合のみ `0.0.0.0` 等を指定 | +| `CHROME_USER_DATA_DIR` | `/tmp/chrome-debug` | 起動プロファイル。空にするとデフォルトプロファイル (ログイン済み Session) を使用 | +| `CHROME_BIN` | `/Applications/Google Chrome.app/Contents/MacOS/Google Chrome` | Chrome バイナリパス | +| `MANUAL_WAIT` | `120` | 手動フォールバック時の起動待ち秒。`0` で待たず即終了 | + +動作: + +1. `http://host.docker.internal:9222/json/version` に疎通すれば **起動済み** とみなし即終了 +2. 未起動なら SSH (`BatchMode=yes`) でホストに接続し、Chrome をバックグラウンド (`nohup ... &`) で起動 +3. CDP エンドポイントが応答するまで最大 30 秒ポーリングして待機 + +### SSH が使えない場合のフォールバック + +`HOST_SSH_USER` 未設定 / コンテナに `ssh` クライアントが無い / SSH 接続・実行に失敗 (鍵未登録・リモートログイン無効・到達不可) のいずれかで、スクリプトは **自動で手動フォールバックに切り替わる**。 + +フォールバック時は、ホスト側で実行すべき起動コマンドをそのまま画面に出力し、`MANUAL_WAIT` 秒 (既定 120s) のあいだ CDP の起動をポーリングして待機する。利用者はその間にホストのターミナルへコマンドを貼り付けて実行すればよい。CI など人手が介在しない環境では `MANUAL_WAIT=0` を指定すれば、案内を出して即座に非ゼロ終了する。 + +> **Note (SSH を使わない代替手段)**: ホスト側に常駐ランチャ (launchd エージェントや FIFO 監視スクリプト、簡易 HTTP エンドポイント等) を置き、コンテナからネットワーク経由でトリガする方法もある。ただし SSH 方式が最も追加実装が少なく確実。X11 forwarding (XQuartz + socat) は「コンテナ内 GUI をホスト画面に表示する」用途であり、本件には不要。 + +> **Note (Linux ホストの場合)**: ホストで sshd が動いていれば同じスクリプトが使える。`CHROME_BIN=google-chrome`、`HOST_SSH_HOST` をホスト IP (`172.17.0.1` 等) に設定する。GUI セッションへの接続には `DISPLAY` 等の追加考慮が必要。 + +## conftest.py への統合 + +`browser.mode: cdp-remote` の場合、pytest-playwright の通常のブラウザ起動をバイパスし、 +`connectOverCDP()` で既存 Chrome に接続する fixture を有効化する必要がある。 + +`scenario-test/conftest.py` に以下を追加する。 + +```python +import pytest +from playwright.sync_api import Browser, BrowserType + +@pytest.fixture(scope="session") +def browser( + browser_type: BrowserType, + browser_type_launch_args: dict, + pwk_config, +) -> Browser: + """browser.mode に応じてブラウザ接続を切り替える。 + + - local: pytest-playwright デフォルト (chromium.launch()) + - cdp-remote: chromium.connect_over_cdp(endpoint) + """ + browser_cfg = pwk_config.browser + # slow_mo: browser_type_launch_args が優先、なければ config の slow_mo_ms + _slow_mo = browser_type_launch_args.get( + "slow_mo", pwk_config.playwright.slow_mo_ms or None + ) + if browser_cfg.mode == "cdp-remote": + if browser_type.name != "chromium": + pytest.fail( + f"cdp-remote モードは Chromium 専用です (現在: {browser_type.name})。" + "--browser chromium を指定するか、browser.mode を local に変更してください。" + ) + browser = browser_type.connect_over_cdp( + browser_cfg.cdp_endpoint, + slow_mo=_slow_mo, + ) + yield browser + # CDP 接続の場合、close() は接続を切断 (disconnect) するだけで、 + # リモートブラウザ自体は終了しない。 + browser.close() + else: + launch_args = {**browser_type_launch_args} + launch_args.setdefault("headless", pwk_config.playwright.headless) + if _slow_mo is not None: + launch_args.setdefault("slow_mo", _slow_mo) + browser = browser_type.launch(**launch_args) + yield browser + browser.close() +``` + +### CDP モードでの既存セッション再利用 + +`browser.new_context()` は新規コンテキストを作成するため、既存のログイン Session は引き継がれない。 +`cdp-remote` モードでは、テンプレートの `conftest.py` が `context` / `page` fixture を自動的にオーバーライドし、 +CDP 接続先の既存コンテキスト (ログイン済み Session) を返す。標準のテストコードは無変更で既存セッションを利用できる。 + +```python +@pytest.fixture(scope="session") +def context(browser, pwk_config, _cdp_default_context): + """cdp-remote: 既存コンテキスト / local: 新規コンテキスト""" + if pwk_config.browser.mode == "cdp-remote" and _cdp_default_context is not None: + yield _cdp_default_context + else: + ctx = browser.new_context() + yield ctx + ctx.close() + +@pytest.fixture(scope="session") +def page(context, pwk_config): + """cdp-remote: 既存ページ / local: 新規ページ""" + if pwk_config.browser.mode == "cdp-remote" and context.pages: + yield context.pages[0] + else: + pg = context.new_page() + yield pg + pg.close() +``` + +## run.sh での利用 + +`cdp-remote` モード時は `playwright install chromium` が不要。`run.sh` は初回セットアップで +`playwright install` を実行するが、接続先がリモートの場合はスキップして問題ない。 + +```bash +# エンドポイントの疎通確認 +curl -s http://host.docker.internal:9222/json/version | python3 -m json.tool +``` + +## ネットワーク別接続ガイド + +Chrome はデフォルトで `127.0.0.1` にバインドするため、同一ホストからしか CDP エンドポイントにアクセスできない。 +Docker コンテナや WSL2 からリモート接続する場合は、次のいずれかで到達性を確保する。 + +### 方法 1: `--remote-debugging-address=0.0.0.0` (推奨) + +Chrome 起動時に全インターフェースでリッスンさせる。最もシンプル。フラグの詳細は冒頭の表を参照。 + +### 方法 2: socat によるポートフォワード (Linux) + +Chrome を `127.0.0.1` バインドのまま維持し、socat でリモートからのアクセスを中継する。 + +```bash +socat TCP-LISTEN:9222,bind=0.0.0.0,reuseaddr,fork TCP:127.0.0.1:9222 +``` + +### 方法 3: netsh portproxy (Windows → WSL2) + +```powershell +# 管理者権限の PowerShell で実行 +netsh interface portproxy add v4tov4 ` + listenaddress=0.0.0.0 listenport=9222 ` + connectaddress=127.0.0.1 connectport=9222 + +netsh interface portproxy show all +netsh interface portproxy delete v4tov4 listenaddress=0.0.0.0 listenport=9222 +``` + +### 接続先の早見表 + +| 実行環境 | Chrome の場所 | 推奨方法 | CDP エンドポイント | +|---|---|---|---| +| ローカル (同一ホスト) | 同一ホスト | 設定不要 | `http://localhost:9222` | +| Docker → ホスト (macOS) | macOS ホスト | 方法 1 | `http://host.docker.internal:9222` | +| Docker → ホスト (Linux) | Linux ホスト | 方法 1 or 2 | `http://host.docker.internal:9222` or `http://172.17.0.1:9222` | +| Docker (WSL2) → Windows | Windows ホスト | 方法 1 or 3 | `http://host.docker.internal:9222` | +| WSL2 → Windows | Windows ホスト | 方法 1 or 3 | `http://$(grep nameserver /etc/resolv.conf \| awk '{print $2}'):9222` | + +## トラブルシュート + +### 共通 + +| 症状 | 原因 | 対策 | +|---|---|---| +| `connect_over_cdp` で接続拒否 | Chrome が起動していない / ポートが違う | `curl http:///json/version` で確認 | +| WebSocket handshake 失敗 | Host ヘッダ不一致 | Chrome 起動時に `--remote-allow-origins=*` を付与 | +| ページ操作が異常に遅い | VPN / DNS 解決の遅延 | `extra_hosts` で IP 直指定 | + +### Windows (WSL2) 固有 + +| 症状 | 原因 | 対策 | +|---|---|---| +| `host.docker.internal` 解決不能 | Docker Desktop 未使用 or 古いバージョン | Docker Desktop を使用するか、WSL2 直接の場合は Windows ホスト IP を直接指定 | +| IPv6 でバインドされる | WSL2 が IPv6 優先 | listen address に `0.0.0.0` を明示 | +| `netsh portproxy` で接続ループ | portproxy の自己参照 | `--remote-allow-origins=*` を使い proxy を廃止 | +| mirrored mode で動かない | mirrored は localhost 共有だが CDP の WS 接続でポート競合 | NAT mode に戻す | + +### macOS 固有 + +| 症状 | 原因 | 対策 | +|---|---|---| +| `host.docker.internal` 解決不能 | Docker Desktop が古い / Linux Docker | `--add-host=host.docker.internal:host-gateway` を指定 | +| ファイアウォールでブロック | macOS のアプリファイアウォール | システム設定 > ネットワーク > ファイアウォール で Chrome を許可 | +| SSH 起動で Chrome が表示されない / WindowServer エラー | コンソール非ログインユーザーで SSH した | コンソールにログイン中の本人ユーザーで SSH する | +| `start-host-chrome.sh` が SSH で認証失敗 | リモートログイン未有効 / 鍵未登録 | `sudo systemsetup -setremotelogin on` と `authorized_keys` 登録を確認 | + +## CDP 接続のメリット + +- **GUI Chrome をそのまま操作可能** — OBS 録画可、人間と AI の協調操作が可能 +- **ログイン済み Session の再利用** — Google / AWS / Slack 等の MFA 済み Session をそのまま使える +- **ブラウザ拡張機能が有効** — テスト時にも拡張機能の影響を確認可能 +- **AI Agent との相性** — Claude Code / Browser Use / OpenHands がリアルブラウザを操作 diff --git a/plugins/ndf-shared/skills/playwright-authoring/scripts/start-host-chrome.sh b/plugins/ndf-shared/skills/playwright-authoring/scripts/start-host-chrome.sh new file mode 100755 index 00000000..8c7b1d08 --- /dev/null +++ b/plugins/ndf-shared/skills/playwright-authoring/scripts/start-host-chrome.sh @@ -0,0 +1,172 @@ +#!/usr/bin/env bash +# コンテナ内から SSH 経由でホスト (macOS / Linux) の Chrome を +# リモートデバッグモードで起動するスクリプト。 +# +# 背景: +# Docker コンテナはホストとプロセス空間が分離されているため、 +# コンテナから直接ホストのプロセスを起動できない。 +# ホストの sshd (macOS: システム設定 > 共有 > リモートログイン) に接続し、 +# 起動コマンドを実行することで間接的にホスト Chrome を起動する。 +# +# SSH が使えない場合 (鍵未登録・リモートログイン無効など) は、 +# ホスト側で手動実行する起動コマンドを案内し、起動されるまで待機する +# フォールバックに切り替わる。 +# +# 前提 (SSH 自動起動を使う場合のみ・ホスト側で一度だけ設定): +# 1) リモートログインを有効化 (macOS: sudo systemsetup -setremotelogin on) +# 2) コンテナの公開鍵を ~/.ssh/authorized_keys に登録 (パスワードレス実行) +# 3) コンソールにログイン中の本人ユーザーで SSH すること +# (GUI アプリは WindowServer 接続のためコンソールセッション所有者が必要) +# +# 使い方 (コンテナ内): +# # SSH 自動起動 +# HOST_SSH_USER= ./scripts/start-host-chrome.sh +# # SSH を使わず手動起動の案内のみ +# ./scripts/start-host-chrome.sh +# +# 環境変数: +# HOST_SSH_USER ホストのログインユーザー名。未設定なら手動フォールバック +# HOST_SSH_HOST SSH 接続先 (default: host.docker.internal) +# CDP_HOST CDP 疎通確認先ホスト (default: HOST_SSH_HOST) +# CDP_PORT リモートデバッグポート (default: 9222) +# CDP_BIND_ADDRESS Chrome の listen address。空 (default) なら付与せず +# Chrome 既定の loopback bind (macOS Docker Desktop は +# host.docker.internal がホスト loopback に到達するため +# これで動作する)。Linux/WSL2 等で loopback bind だと +# コンテナから到達できない場合のみ 0.0.0.0 等を指定する。 +# 0.0.0.0 は全インターフェース公開のためセキュリティ注意。 +# CHROME_USER_DATA_DIR 起動プロファイル (default: /tmp/chrome-debug) +# 空にするとデフォルトプロファイル (ログイン済み Session) を使用 +# CHROME_BIN Chrome バイナリパス +# (default: /Applications/Google Chrome.app/Contents/MacOS/Google Chrome) +# STARTUP_TIMEOUT SSH 起動後の待機タイムアウト秒 (default: 30) +# MANUAL_WAIT 手動フォールバック時の待機秒。0 で待たず即終了 (default: 120) +set -euo pipefail + +HOST_SSH_USER="${HOST_SSH_USER:-}" +HOST_SSH_HOST="${HOST_SSH_HOST:-host.docker.internal}" +CDP_HOST="${CDP_HOST:-$HOST_SSH_HOST}" +CDP_PORT="${CDP_PORT:-9222}" +CDP_BIND_ADDRESS="${CDP_BIND_ADDRESS:-}" +CHROME_USER_DATA_DIR="${CHROME_USER_DATA_DIR-/tmp/chrome-debug}" +CHROME_BIN="${CHROME_BIN:-/Applications/Google Chrome.app/Contents/MacOS/Google Chrome}" +STARTUP_TIMEOUT="${STARTUP_TIMEOUT:-30}" +MANUAL_WAIT="${MANUAL_WAIT:-120}" + +# curl は冪等チェック・起動待機・手動フォールバックの全経路で CDP 疎通確認に +# 使う必須コマンド。無いと終了コード 127 で常に未起動扱いとなり、起動成功時でも +# タイムアウトしてしまうため、ここでフェイルファストする。 +if ! command -v curl >/dev/null 2>&1; then + echo "✗ curl が見つかりません。CDP 疎通確認に必須です。" >&2 + echo " コンテナに curl をインストールしてから再実行してください" >&2 + echo " (例: apt-get install -y curl / apk add curl)。" >&2 + exit 1 +fi + +cdp_up() { + # --max-time でネットワークハング時も待機ループ周期が壊れないようにする + curl -sf --max-time 2 "http://${CDP_HOST}:${CDP_PORT}/json/version" >/dev/null 2>&1 +} + +# --user-data-dir は空文字なら付与しない (デフォルトプロファイル使用) +userdata_arg="" +if [ -n "${CHROME_USER_DATA_DIR}" ]; then + userdata_arg="--user-data-dir='${CHROME_USER_DATA_DIR}'" +fi + +# --remote-debugging-address は CDP_BIND_ADDRESS が空なら付与しない。 +# 既定 (空) では Chrome は loopback (127.0.0.1) のみ listen する。macOS +# Docker Desktop は host.docker.internal がホストの loopback に到達するため +# これで動作する (ユーザー実証済み・0.0.0.0 不要)。 +# Linux/WSL2 等で loopback bind だとコンテナから到達できない場合のみ +# CDP_BIND_ADDRESS=0.0.0.0 等を指定する。0.0.0.0 は CDP を全インターフェース +# へ公開し、CDP は認証なしでブラウザ操作できるためセキュリティに注意すること。 +bind_arg="" +if [ -n "${CDP_BIND_ADDRESS}" ]; then + bind_arg="--remote-debugging-address=${CDP_BIND_ADDRESS} " +fi + +# ホスト側で実行する Chrome 起動コマンド (人間がコピペできる体裁) +host_launch_cmd() { + printf '"%s" --remote-debugging-port=%s %s%s --remote-allow-origins=* --disable-features=DialMediaRouteProvider' \ + "${CHROME_BIN}" "${CDP_PORT}" "${bind_arg}" "${userdata_arg}" +} + +# 手動フォールバック: ホストで実行するコマンドを案内し、起動を待機する +manual_fallback() { + local reason="$1" + echo "" >&2 + echo "──────────────────────────────────────────────────────────────" >&2 + echo "⚠ SSH 自動起動を利用できません (${reason})。" >&2 + echo " ホスト (mac) 側のターミナルで以下を実行してください:" >&2 + echo "" >&2 + echo " $(host_launch_cmd)" >&2 + echo "" >&2 + echo "──────────────────────────────────────────────────────────────" >&2 + + if [ "${MANUAL_WAIT}" -le 0 ]; then + echo "✗ Chrome 未起動のまま終了します (MANUAL_WAIT=0)。" >&2 + exit 1 + fi + + echo "→ ホストでの起動を待機中 (最大 ${MANUAL_WAIT}s, Ctrl-C で中断)..." >&2 + # seq 外部依存も bash 専用 for ((...)) も避け、POSIX 互換 while で待機する + # (最小コンテナ / /bin/sh しかない環境でも動作) + i=0 + while [ "$i" -lt "$MANUAL_WAIT" ]; do + if cdp_up; then + echo "✓ Chrome 起動を検知しました: http://${CDP_HOST}:${CDP_PORT}" + exit 0 + fi + sleep 1 + i=$((i + 1)) + done + echo "✗ 待機タイムアウト。手動起動後に再実行してください。" >&2 + exit 1 +} + +# 1) 既に起動済みなら何もしない (冪等) +if cdp_up; then + echo "✓ Chrome は既に CDP http://${CDP_HOST}:${CDP_PORT} で起動済みです" + exit 0 +fi + +# 2) HOST_SSH_USER 未設定 → 手動フォールバック +if [ -z "${HOST_SSH_USER}" ]; then + manual_fallback "HOST_SSH_USER が未設定" +fi + +# 3) ssh コマンドが無い → 手動フォールバック +if ! command -v ssh >/dev/null 2>&1; then + manual_fallback "コンテナに ssh クライアントが無い" +fi + +# 4) SSH でホストに接続し、Chrome をバックグラウンド起動 +echo "→ ${HOST_SSH_USER}@${HOST_SSH_HOST} で Chrome を起動します..." +# &2 +exit 1 diff --git a/plugins/ndf-shared/skills/playwright-evidence-drive/SKILL.md b/plugins/ndf-shared/skills/playwright-evidence-drive/SKILL.md deleted file mode 100644 index 43a7d46a..00000000 --- a/plugins/ndf-shared/skills/playwright-evidence-drive/SKILL.md +++ /dev/null @@ -1,190 +0,0 @@ ---- -name: playwright-evidence-drive -description: "Upload Playwright evidence to Google Drive." -when_to_use: "テストエビデンスを Google Drive に保管・共有したいとき / テスト結果を Google Docs としてチームに配布したいとき / Drive 上のエビデンスリンクを report に埋め込みたいとき。Triggers: 'Drive にアップロード', 'Drive 共有', 'エビデンス保管', 'evidence drive', 'pwk-drive-folder', 'テスト結果共有', 'Google Drive エビデンス', 'trace アップロード', '動画アップロード', 'report を Docs に', 'エビデンス配布'" -allowed-tools: - - Read - - Bash(python *) - - Bash(uv *) ---- - -# Playwright Evidence → Google Drive 保管 - -テスト実行後のエビデンス一式を Google Drive に保管し、共有可能にする。 - -## 前提条件 - -- `/ndf:google-auth` で OAuth2 認証が完了していること (drive.file スコープ) -- テスト実行済みで `reports//` にエビデンスが存在すること - -## アップロード対象 - -| ファイル | 種別 | セキュリティ考慮 | -|---|---|---| -| `video.mp4` | テスト動画 | 画面に表示された情報が含まれる | -| `trace.zip` | Playwright Trace | DOM snapshot + 操作ログ + Cookie/localStorage | -| `request.har` | ネットワーク通信ログ | HTTP request/response body を含む場合あり | -| `report.md` | テスト結果サマリ | URL + テスト名程度 | -| `body_check.jsonl` | PHP/SSR エラー詳細 | ソースコード片を含む場合あり | -| `screenshot-*.png` | 失敗時スクリーンショット | 画面に表示された情報 | - -**セキュリティ注意**: trace.zip / HAR には認証情報 (Cookie, localStorage, Basic Auth) や -入力内容が含まれる可能性がある。アップロード先は **private folder** + **信頼できる共有相手** に限定すること。 - -## 方法 1: テスト実行時の自動アップロード - -`--pwk-drive-folder` を指定すると `pytest_sessionfinish` hook で自動アップロードされる。 - -```bash -./scenario-test/run.sh --pwk-drive-folder= -``` - -動作: -1. テスト終了後に `pytest_sessionfinish` が発火 -2. `report.md` をアップロード -3. 各テストの `trace.zip` / `*.har` / `*.mp4` / `body_check.jsonl` をアップロード -4. 全ファイルは非公開 (private) でアップロードされる - -## 方法 2: 手動アップロード (scripts) - -テスト実行後に個別にアップロードする場合。スクリプトは `playwright-kit-ops/scripts/` に配置。 - -### 単一ファイルアップロード - -```bash -cd scenario-test -uv run python scripts/upload_evidence.py reports//test_login/trace.zip \ - --kind trace \ - --parent-folder-id -``` - -オプション: -- `--kind {trace|har|video|any}` — ファイル種別 (拡張子から自動判定も可) -- `--parent-folder-id ` — Drive 上のアップロード先フォルダ ID -- `--public` — anyone/read 権限を付与 (trace viewer URL 生成に必要) - -### ディレクトリ一括アップロード - -```bash -uv run python scripts/gdrive_upload_dir.py \ - --local reports// \ - --parent -``` - -ディレクトリ構造を保ったまま Drive にミラーする。 -サブフォルダも再帰的に作成される。 - -### report.md → Google Docs 変換 - -```bash -uv run python scripts/upload_md_as_gdoc.py \ - --md reports//report.md \ - --parent \ - --name "E2E テスト報告書 2026-05-26" -``` - -Markdown を Google Docs 形式に変換してアップロード。 -テーブル・リスト・見出しが Docs のネイティブ形式に変換される。 - -### Google Docs にエビデンス Drive リンクを埋め込み - -```bash -uv run python scripts/build_gdoc_with_drive_links.py \ - --md reports//report.md \ - --folder \ - --run-id \ - --name "E2E テスト報告書 2026-05-26" -``` - -1. Drive 上の `` 配下の `` フォルダからファイル一覧を取得 -2. `report.md` 内の相対パスリンク (`./TC-XX/trace.zip`) を Drive URL に書き換え -3. 書き換え済み Markdown を Google Docs としてアップロード - -→ チームメンバーが Docs 上で report を読みながら、エビデンスへの Drive リンクをクリックして確認できる。 - -## 推奨ワークフロー - -``` -[テスト実行] - ./scenario-test/run.sh --pwk-overlay - ↓ -[ローカル確認] - reports//report.md で結果確認 - ↓ -[Drive 一括アップロード] - uv run python scripts/gdrive_upload_dir.py --local reports// --parent - ↓ -[Docs 変換 + リンク埋め込み] - uv run python scripts/build_gdoc_with_drive_links.py --md reports//report.md --folder --run-id --name "報告書" - ↓ -[共有] - Docs URL をチーム (Slack / Google Chat) に共有 -``` - -ワンコマンドで全てを行う場合: - -```bash -./scenario-test/run.sh --pwk-drive-folder= --pwk-overlay -``` - -## Drive フォルダ構成の推奨 - -``` -E2E テスト証跡/ ← 共有ドライブ or チームフォルダ -├── <プロジェクト名>/ -│ ├── 20260526-134500/ ← run-id (自動生成) -│ │ ├── report.md -│ │ ├── test_login/ -│ │ │ ├── video.mp4 -│ │ │ ├── trace.zip -│ │ │ └── request.har -│ │ └── test_admin_dashboard/ -│ │ ├── video.mp4 -│ │ └── trace.zip -│ └── report (Google Docs) ← build_gdoc_with_drive_links で生成 -``` - -## Trace Viewer 連携 - -`--public` でアップロードした trace.zip は Playwright Trace Viewer で直接開ける: - -```bash -uv run python scripts/upload_evidence.py reports/.../trace.zip \ - --kind trace --public --parent-folder-id -``` - -出力例: -``` -playwright_trace_viewer: https://trace.playwright.dev/?trace=https%3A%2F%2Fdrive.google.com%2Fuc%3Fexport%3Ddownload%26id%3D... -``` - -この URL を共有すると、インストール不要でブラウザ上から trace を再生できる。 - -**注意**: `--public` は anyone/read を付与するため、trace 内の機密情報 (Cookie, 入力値) が -公開される。社内限定の場合は private のまま `playwright show-trace` をローカルで使うこと。 - -## トラブルシュート - -| 症状 | 原因 | 対策 | -|---|---|---| -| `google_auth スキルが見つかりません` | google-auth スキル未インストール | `GOOGLE_AUTH_SCRIPTS` env を設定、または `/ndf:google-auth` で認証セットアップ | -| `HttpError 403: insufficient permissions` | drive.file スコープ不足 | `/ndf:google-auth` で再認証 (`drive.file` スコープ指定) | -| `HttpError 404: File not found` | FOLDER_ID が間違っている / アクセス権なし | Drive で共有フォルダ ID を確認 | -| `resumable upload failed` | ファイルサイズが大きい / ネットワーク不安定 | 再試行。動画は mp4 (H.264) で容量を抑える | -| pytest 後に自動アップロードされない | `--pwk-drive-folder` 未指定 | CLI 引数を確認 | - -## 環境変数 - -| 変数 | 用途 | 例 | -|---|---|---| -| `GOOGLE_AUTH_SCRIPTS` | google-auth スキルの scripts/ パス | `~/.claude/skills/google-auth/scripts` | -| `PWK_DRIVE_FOLDER` | デフォルトの Drive アップロード先 (将来対応予定) | `1ABCxyz...` | - -## 関連 Skill - -- `/ndf:playwright-execution` — テスト実行 + エビデンス収集 (Drive アップロードの前段) -- `/ndf:playwright-report` — Markdown レポート生成 -- `/ndf:playwright-kit-ops` — スクリプト実行 (upload_evidence 等のスクリプトはここに配置) -- `/ndf:google-auth` — Google API OAuth2 認証 -- `/ndf:google-drive` — Google Drive 汎用操作 -- `/ndf:playwright-scenario-test` — 全機能統括 diff --git a/plugins/ndf-shared/skills/playwright-evidence/SKILL.md b/plugins/ndf-shared/skills/playwright-evidence/SKILL.md new file mode 100644 index 00000000..f66d8edc --- /dev/null +++ b/plugins/ndf-shared/skills/playwright-evidence/SKILL.md @@ -0,0 +1,172 @@ +--- +name: playwright-evidence +description: "Generate the Playwright test report and store its evidence on Google Drive. Use when generating report.md, sharing E2E test results, or uploading video / trace / HAR evidence to Drive (テストレポート / テスト結果共有 / テスト報告書 / エビデンス保管 / Drive アップロード)." +when_to_use: "レポート生成 / エビデンスのチーム配布 / Drive リンクを埋め込んだ Google Docs 作成が必要なとき。Triggers: 'report.md', 'pwk-drive-folder', 'upload_evidence', 'gdrive_upload_dir', 'trace viewer', 'report を Docs に'" +allowed-tools: + - Read + - Bash(python *) + - Bash(uv *) + - Bash(pytest *) +--- + +# Playwright 証跡とレポート + +テスト実行後に Markdown レポートを生成し、エビデンス一式を Google Drive に保管して共有可能にする。 + +## 前提条件 + +- テスト実行済みで `reports//` にエビデンスが存在すること (`/ndf:playwright-authoring`) +- Drive へ保管する場合のみ、`/ndf:google-auth` で OAuth2 認証が完了していること (drive.file スコープ) + +## レポート生成 + +`pytest_terminal_summary` hook で `reports//report.md` が自動生成される。特別な設定は不要。 + +```bash +./scenario-test/run.sh +# → reports//report.md が生成される +``` + +| セクション | 内容 | +|---|---| +| サマリ表 | nodeid, role, page_role, 結果, 実行時間, エラー数 | +| 失敗詳細 | FAIL/ERROR のテストごとの詳細情報 | +| body_check 違反 | PHP/SSR エラー検出の詳細 (URL, パターン, スニペット) | +| エビデンスリンク | video, trace, HAR, screenshot へのパス | + +`scenario.config.yaml` の `report` セクションで表題等を制御する。 + +```yaml +report: + title: "シナリオ E2E テスト 実施報告書" + test_plan_link: "./test-plan.md" + phase_labels: {} +``` + +## アップロード対象とセキュリティ + +| ファイル | 種別 | セキュリティ考慮 | +|---|---|---| +| `video.mp4` | テスト動画 | 画面に表示された情報が含まれる | +| `trace.zip` | Playwright Trace | DOM snapshot + 操作ログ + Cookie/localStorage | +| `request.har` | ネットワーク通信ログ | HTTP request/response body を含む場合あり | +| `report.md` | テスト結果サマリ | URL + テスト名程度 | +| `body_check.jsonl` | PHP/SSR エラー詳細 | ソースコード片を含む場合あり | +| `screenshot-*.png` | 失敗時スクリーンショット | 画面に表示された情報 | + +**セキュリティ注意**: trace.zip / HAR には認証情報 (Cookie, localStorage, Basic Auth) や +入力内容が含まれる可能性がある。アップロード先は **private folder** + **信頼できる共有相手** に限定すること。 + +## 方法 1: テスト実行時の自動アップロード + +`--pwk-drive-folder` を指定すると `pytest_sessionfinish` hook で自動アップロードされる。 + +```bash +./scenario-test/run.sh --pwk-drive-folder= +``` + +`report.md` と各テストの `trace.zip` / `*.har` / `*.mp4` / `body_check.jsonl` が、 +すべて非公開 (private) でアップロードされる。 + +## 方法 2: 手動アップロード (scripts) + +スクリプトは `playwright-kit-ops/scripts/` に配置されている。 + +```bash +cd scenario-test + +# 単一ファイル +uv run python scripts/upload_evidence.py reports//test_login/trace.zip \ + --kind trace --parent-folder-id + +# ディレクトリ一括 (構造を保ったまま Drive にミラー。サブフォルダも再帰作成) +uv run python scripts/gdrive_upload_dir.py --local reports// --parent + +# report.md → Google Docs 変換 (表・リスト・見出しを Docs ネイティブ形式へ) +uv run python scripts/upload_md_as_gdoc.py --md reports//report.md \ + --parent --name "E2E テスト報告書" + +# Google Docs にエビデンスの Drive リンクを埋め込み +uv run python scripts/build_gdoc_with_drive_links.py --md reports//report.md \ + --folder --run-id --name "E2E テスト報告書" +``` + +`upload_evidence.py` の主なオプション: + +- `--kind {trace|har|video|any}` — ファイル種別 (拡張子から自動判定も可) +- `--parent-folder-id ` — Drive 上のアップロード先フォルダ ID +- `--public` — anyone/read 権限を付与 (trace viewer URL 生成に必要) + +`build_gdoc_with_drive_links.py` は、Drive 上の `` フォルダのファイル一覧を取得し、 +`report.md` 内の相対パスリンク (`./TC-XX/trace.zip`) を Drive URL に書き換えてから Docs 化する。 +チームメンバーは Docs 上で report を読みながらエビデンスへのリンクをクリックできる。 + +## 推奨ワークフロー + +``` +[テスト実行] ./scenario-test/run.sh --pwk-overlay + ▼ +[ローカル確認] reports//report.md で結果確認 + ▼ +[Drive 一括保管] gdrive_upload_dir.py --local reports// --parent + ▼ +[Docs 化 + リンク埋め込み] build_gdoc_with_drive_links.py ... + ▼ +[共有] Docs URL をチーム (Slack / Google Chat) に共有 +``` + +ワンコマンドで済ませる場合: `./scenario-test/run.sh --pwk-drive-folder= --pwk-overlay` + +### Drive フォルダ構成の推奨 + +``` +E2E テスト証跡/ ← 共有ドライブ or チームフォルダ +├── <プロジェクト名>/ +│ ├── 20260526-134500/ ← run-id (自動生成) +│ │ ├── report.md +│ │ └── test_login/ +│ │ ├── video.mp4 +│ │ ├── trace.zip +│ │ └── request.har +│ └── report (Google Docs) ← build_gdoc_with_drive_links で生成 +``` + +## Trace Viewer 連携 + +`--public` でアップロードした trace.zip は Playwright Trace Viewer で直接開ける。 + +```bash +uv run python scripts/upload_evidence.py reports/.../trace.zip \ + --kind trace --public --parent-folder-id +# → playwright_trace_viewer: https://trace.playwright.dev/?trace=... +``` + +この URL を共有すると、インストール不要でブラウザ上から trace を再生できる。 + +**注意**: `--public` は anyone/read を付与するため、trace 内の機密情報 (Cookie, 入力値) が +公開される。社内限定の場合は private のまま `playwright show-trace` をローカルで使うこと。 + +## 環境変数 + +| 変数 | 用途 | 例 | +|---|---|---| +| `GOOGLE_AUTH_SCRIPTS` | google-auth skill の scripts/ パス | `~/.claude/skills/google-auth/scripts` | +| `PWK_DRIVE_FOLDER` | デフォルトの Drive アップロード先 (将来対応予定) | `1ABCxyz...` | + +## トラブルシュート + +| 症状 | 原因 | 対策 | +|---|---|---| +| `google_auth スキルが見つかりません` | google-auth skill 未インストール | `GOOGLE_AUTH_SCRIPTS` env を設定、または `/ndf:google-auth` で認証セットアップ | +| `HttpError 403: insufficient permissions` | drive.file スコープ不足 | `/ndf:google-auth` で再認証 (`drive.file` スコープ指定) | +| `HttpError 404: File not found` | FOLDER_ID が間違っている / アクセス権なし | Drive で共有フォルダ ID を確認 | +| `resumable upload failed` | ファイルサイズが大きい / ネットワーク不安定 | 再試行。動画は mp4 (H.264) で容量を抑える | +| pytest 後に自動アップロードされない | `--pwk-drive-folder` 未指定 | CLI 引数を確認 | + +## 関連 Skill + +- `/ndf:playwright-authoring` — スクリプト作成と実行 (前段) +- `/ndf:playwright-planning` — テスト計画 +- `/ndf:playwright-kit-ops` — 実行環境の運用 (アップロードスクリプトの配置元) +- `/ndf:google-auth` — Google API OAuth2 認証 +- `/ndf:google-drive` — Google Drive 汎用操作 diff --git a/plugins/ndf-shared/skills/playwright-execution/SKILL.md b/plugins/ndf-shared/skills/playwright-execution/SKILL.md deleted file mode 100644 index f99970cd..00000000 --- a/plugins/ndf-shared/skills/playwright-execution/SKILL.md +++ /dev/null @@ -1,101 +0,0 @@ ---- -name: playwright-execution -description: "Run Playwright E2E tests with evidence and metrics." -when_to_use: "E2E テストの実行 / エビデンス収集 / 動画エビデンス / accessibility チェック / Core Web Vitals 計測が必要なとき。テストスクリプト作成済みであることが前提。Triggers: 'E2E テスト実行', 'テスト実行', '動画エビデンス', 'エビデンス収集', 'テスト証跡', 'a11y テスト', 'accessibility テスト', 'axe-core', 'WCAG', 'Core Web Vitals', 'Web Vitals', 'LCP', 'CLS', 'body_check', 'overlay', '字幕', 'カーソル'" -allowed-tools: - - Read - - Bash(uv *) - - Bash(pytest *) - - Bash(npx *) - - Bash(playwright *) - - Bash(python *) ---- - -# Playwright Execution (テスト実行 + エビデンス収集) - -テストスクリプト作成済みの状態で E2E テストを実行し、エビデンスを収集する。 - -## 前提条件 - -- テストスクリプトが `tests/` に作成済みであること (`/ndf:playwright-script-creation` で作成) -- `scenario.config.yaml` が設定済みであること - -## 大原則 - -**エビデンス動画はデフォルト ON**。全テストで常に動画を取得する。 -明示的にスキップする場合のみ `--pwk-no-video` を指定する。 - -## 実行コマンド - -```bash -./scenario-test/run.sh # 全テスト (動画 ON) -./scenario-test/run.sh -k test_admin # フィルタ -./scenario-test/run.sh --pwk-overlay # 字幕 + カーソル付き動画 -./scenario-test/run.sh --pwk-no-video # 動画のみ OFF -./scenario-test/run.sh --pwk-no-evidence # 全エビデンス OFF (HAR/trace/動画) -``` - -## エビデンス種別 - -| 種別 | デフォルト | OFF フラグ | 説明 | -|---|---|---|---| -| video | **ON** | `--pwk-no-video` | 全テストの動画を取得 | -| trace | ON (retain-on-failure) | `--pwk-no-evidence` | Playwright Trace (DOM + 操作ログ) | -| HAR | ON (minimal) | `--pwk-har-mode none` | ネットワーク通信ログ | -| screenshot | ON (only-on-failure) | `--pwk-no-evidence` | 失敗時スクリーンショット | - -## overlay (赤丸カーソル + 字幕) - -`--pwk-overlay` フラグで全テストの動画にオーバーレイが適用される。 - -API 詳細・使用例は `playwright_kit/overlay.py` を参照。主要関数: `set_caption()`, `flash_click()`, `hide_cursor()`。 - -## 品質計測 - -### accessibility (axe-core) - -`@pytest.mark.page_role` marker が付いたテストで auto_roles にマッチする場合に自動実行。 -設定は `scenario.config.yaml` の `accessibility:` セクションで制御。→ 設定例は `templates/scenario.config.yaml` を参照。 - -### Core Web Vitals - -`@pytest.mark.page_role` marker + auto_roles マッチで LCP/CLS/TTFB/longest_task を自動計測。 -設定は `scenario.config.yaml` の `web_vitals:` セクションで制御。→ 設定例は `templates/scenario.config.yaml` を参照。 - -### body_check (PHP/SSR エラー検出) - -`page.on("response")` で全 HTML レスポンスを監視し、`Fatal error` 等を検出。デフォルト有効。 -`@pytest.mark.no_body_check` で個別 opt-out 可能。→ 設定例は `templates/scenario.config.yaml` の `body_check:` セクションを参照。 - -## 成果物 - -``` -reports// -├── report.md # テスト結果サマリ -├── / -│ ├── video.mp4 # テスト動画 (デフォルト ON) -│ ├── trace.zip # Playwright Trace -│ ├── request.har # ネットワーク通信ログ -│ ├── body_check.jsonl # body_check 違反詳細 -│ └── screenshot-*.png # スクリーンショット -``` - -## CLI options - -| option | 役割 | -|---|---| -| `--pwk-config ` | `scenario.config.yaml` のパス | -| `--pwk-out-dir ` | 成果物出力先 (default: `reports//`) | -| `--pwk-no-video` | 動画収集を OFF (デフォルトは ON) | -| `--pwk-no-evidence` | HAR / trace / video の収集を全て OFF | -| `--pwk-har-mode {minimal,full,none}` | HAR 録画モード (default: minimal) | -| `--pwk-overlay` | overlay (赤丸カーソル + 字幕) を ON | - -## 関連 Skill - -- `/ndf:playwright-script-creation` — テストスクリプト作成 (実行の前段) -- `/ndf:playwright-report` — Markdown レポート生成 -- `/ndf:playwright-kit-ops` — スクリプト実行 (init_project / スキャン) -- `/ndf:playwright-browser-connect` — ブラウザ接続構成 (local / CDP remote) -- `/ndf:playwright-evidence-drive` — エビデンス Google Drive 保管 -- `/ndf:playwright-scenario-test` — 全機能統括 diff --git a/plugins/ndf-shared/skills/playwright-kit-ops/SKILL.md b/plugins/ndf-shared/skills/playwright-kit-ops/SKILL.md index 327c1b09..39cbeb03 100644 --- a/plugins/ndf-shared/skills/playwright-kit-ops/SKILL.md +++ b/plugins/ndf-shared/skills/playwright-kit-ops/SKILL.md @@ -111,9 +111,6 @@ playwright_kit Python パッケージ本体・templates・tests はこの skill ## 関連 Skill -- `/ndf:playwright-test-planning` — テスト計画 (方法論 + チェックリスト) -- `/ndf:playwright-script-creation` — テストスクリプト作成 -- `/ndf:playwright-execution` — テスト実行 + エビデンス収集 (video/trace/overlay/quality) -- `/ndf:playwright-browser-connect` — ブラウザ接続構成 (local / CDP remote) -- `/ndf:playwright-report` — レポート生成 -- `/ndf:playwright-scenario-test` — 全機能統括 +- `/ndf:playwright-planning` — テスト計画 (方法論 + チェックリスト + ワークフロー全体像) +- `/ndf:playwright-authoring` — スクリプト作成と実行 (テストコード / エビデンス / ブラウザ接続) +- `/ndf:playwright-evidence` — 証跡とレポート (report.md / Google Drive 保管) diff --git a/plugins/ndf-shared/skills/playwright-kit-ops/playwright_kit/fixtures/__init__.py b/plugins/ndf-shared/skills/playwright-kit-ops/playwright_kit/fixtures/__init__.py index b9eb5000..dc5e6685 100644 --- a/plugins/ndf-shared/skills/playwright-kit-ops/playwright_kit/fixtures/__init__.py +++ b/plugins/ndf-shared/skills/playwright-kit-ops/playwright_kit/fixtures/__init__.py @@ -1,4 +1,4 @@ -"""playwright-scenario-test pytest fixtures。 +"""playwright_kit pytest fixtures (E2E シナリオテスト)。 利用者は通常の pytest テストを書き、`pwk_config` / `pwk_role_` 等の fixture をパラメタ宣言するだけで NDF の機能 (config / 認証 / evidence / diff --git a/plugins/ndf-shared/skills/playwright-kit-ops/playwright_kit/pytest_plugin.py b/plugins/ndf-shared/skills/playwright-kit-ops/playwright_kit/pytest_plugin.py index 81d7dffa..d8e46208 100644 --- a/plugins/ndf-shared/skills/playwright-kit-ops/playwright_kit/pytest_plugin.py +++ b/plugins/ndf-shared/skills/playwright-kit-ops/playwright_kit/pytest_plugin.py @@ -1,4 +1,4 @@ -"""playwright-scenario-test の pytest plugin。 +"""playwright_kit の pytest plugin (E2E シナリオテスト)。 CLI options: - ``--pwk-config ``: scenario.config.yaml を指定 @@ -42,7 +42,7 @@ def pytest_addoption(parser: pytest.Parser) -> None: - group = parser.getgroup("pwk", "playwright-scenario-test (playwright_kit)") + group = parser.getgroup("pwk", "playwright E2E scenario test (playwright_kit)") group.addoption( "--pwk-config", action="store", diff --git a/plugins/ndf-shared/skills/playwright-kit-ops/templates/conftest.py.template b/plugins/ndf-shared/skills/playwright-kit-ops/templates/conftest.py.template index 9ad04d43..c6741398 100644 --- a/plugins/ndf-shared/skills/playwright-kit-ops/templates/conftest.py.template +++ b/plugins/ndf-shared/skills/playwright-kit-ops/templates/conftest.py.template @@ -1,6 +1,6 @@ """利用者プロジェクトの ``tests/conftest.py`` 雛形。 -playwright-scenario-test (playwright_kit) を pytest-playwright 上で使うための +playwright_kit を pytest-playwright 上で使うための 共通設定。plugin (``playwright_kit.pytest_plugin``) は entry-point 経由で auto-load されるため、import や ``pytest_plugins`` 宣言は不要。 @@ -29,7 +29,7 @@ from playwright.sync_api import Browser, BrowserType # scenario.config.yaml の browser.mode に応じてブラウザ接続を切り替える。 # - local: pytest-playwright デフォルト (chromium.launch()) # - cdp-remote: connect_over_cdp() で既存 Chrome に CDP 接続 -# → /ndf:playwright-browser-connect 参照 +# → /ndf:playwright-authoring 参照 @pytest.fixture(scope="session") diff --git a/plugins/ndf-shared/skills/playwright-kit-ops/templates/scenario.config.yaml b/plugins/ndf-shared/skills/playwright-kit-ops/templates/scenario.config.yaml index 6bd08b49..b9f7d6ad 100644 --- a/plugins/ndf-shared/skills/playwright-kit-ops/templates/scenario.config.yaml +++ b/plugins/ndf-shared/skills/playwright-kit-ops/templates/scenario.config.yaml @@ -17,7 +17,7 @@ # cdp-remote: Chrome DevTools Protocol 経由でリモートブラウザに接続 # → Windows / macOS のホスト Chrome を GUI 付きで操作可能 # → ログイン済み Session (Google, AWS, Slack 等) をそのまま再利用 -# → 詳細は /ndf:playwright-browser-connect を参照 +# → 詳細は /ndf:playwright-authoring を参照 browser: mode: local # cdp-remote 時のみ有効。環境変数で切り替え推奨: diff --git a/plugins/ndf-shared/skills/playwright-planning/SKILL.md b/plugins/ndf-shared/skills/playwright-planning/SKILL.md new file mode 100644 index 00000000..73039aa0 --- /dev/null +++ b/plugins/ndf-shared/skills/playwright-planning/SKILL.md @@ -0,0 +1,124 @@ +--- +name: playwright-planning +description: "Plan Playwright E2E tests by judging page role and choosing checklists and test techniques. Use when starting E2E scenario testing, designing test cases, or laying out the whole E2E workflow (テスト計画 / テスト設計 / page role / チェックリスト / シナリオテスト)." +when_to_use: "E2E テスト計画の立案 / page role 分類 / テスト技法の選定 / pytest-playwright ワークフロー全体像の把握が必要なとき。Triggers: 'HTSM', 'ISTQB', 'FEW HICCUPPS', 'ISO 29119', 'テスト観点', 'テスト計画書', 'フル E2E'" +allowed-tools: + - Read + - Bash(python *) +--- + +# E2E テスト計画 (理論ベース) + +HTSM / ISTQB / FEW HICCUPPS に基づいて E2E テストシナリオを計画する。 +本 Skill は E2E ワークフローの入口であり、全体像の提示と計画フェーズの実行を担う。 + +## 大原則 + +1. **再現可能なテストスクリプトを実装してからテストを実施する** +2. **テストスクリプトは ndf plugin 非依存でプロジェクトフォルダに設置する** +3. **テスト実行はエビデンス動画を常に取得する** (オプションで明示的にスキップ可能) + +## 全体ワークフロー + +``` +[1] テスト計画 /ndf:playwright-planning ← 本 Skill + │ 対象 URL → page role 判定 → チェックリスト → テスト技法確定 + ▼ +[2] スクリプト作成と実行 /ndf:playwright-authoring + │ テンプレート → 実装 → 再現可能性レビュー → 実行 + エビデンス収集 + │ ※ スクリプトが完成するまでテスト実行に進まない + ▼ +[3] 証跡とレポート /ndf:playwright-evidence + │ reports//report.md 生成 → Google Drive 保管・共有 + ▼ +[任意] 実行環境の運用 /ndf:playwright-kit-ops + init_project / 単発スキャン / アップロードスクリプト (任意タイミング) +``` + +## クイックスタート + +1. プロジェクト初期化: `/ndf:playwright-kit-ops` で `./scripts/init_project.sh /path/to/your-app` を実行 +2. 設定編集: `scenario-test/scenario.config.yaml` +3. テストスクリプト作成: `scenario-test/tests/test_*.py` (→ `/ndf:playwright-authoring`) +4. テスト実行 (動画デフォルト ON): `./scenario-test/run.sh` +5. 動画スキップ: `./scenario-test/run.sh --pwk-no-video` + +→ `your-app/scenario-test/` は ndf plugin 非依存。単体で完結する。 + +## 計画ワークフロー + +``` +[A] 対象 URL を渡される + │ +[B] page role を判定 → scripts/classify_page_role.py --url + ▼ +[C] 該当チェックリストを開く → docs/checklists/checklist-{role}.md + │ 全項目を「適用」or「不適用 (理由付き)」で判定 + ▼ +[D] 必須テスト技法を確定 → docs/03-test-techniques.md § 11 + ▼ +[E] pytest テストを書く → templates/test_.py.template を起点に + ▼ +[F] スクリプト作成と実行へ → /ndf:playwright-authoring + テスト計画が完了するまでスクリプト作成には進まない。 +``` + +## page role 一覧 + +| role | 説明 | 例 | +|---|---|---| +| lp | ランディングページ | トップ、LP | +| list | 一覧ページ | 商品一覧、記事一覧 | +| item | 詳細ページ | 商品詳細、記事詳細 | +| edit | 編集ページ | プロフィール編集 | +| form | 申込・入力フォーム | 会員登録、問い合わせ | +| search | 検索ページ | サイト内検索 | +| dashboard | ダッシュボード | 管理画面トップ | +| auth | 認証ページ | ログイン、パスワードリセット | +| cart-checkout | カート・決済 | ショッピングカート | +| modal-wizard | モーダル・ウィザード | ステップ型入力 | + +## チェックリスト + +`playwright-planning/docs/checklists/` 配下に role 別チェックリストがある。 +`checklist-common.md` が全 role 共通項目 (accessibility / Core Web Vitals / セキュリティ / i18n) で、 +残りは上表の role 名に対応する `checklist-{role}.md` である。 + +## 方法論ドキュメント + +`playwright-planning/docs/` 配下: + +| ファイル | 内容 | +|---|---| +| `README.md` | 方法論ドキュメント全体の索引と利用フロー | +| `01-methodology.md` | HTSM / FEW HICCUPPS / ISO 29119-3 の概要 | +| `02-page-roles.md` | page role 分類の詳細定義 | +| `03-test-techniques.md` | テスト技法 (EP/BVA/Decision Table/Pairwise) + role 必須マッピング | +| `04-playwright-mapping.md` | Playwright API → role / 観点 マッピング | +| `05-bug-report.md` | 不具合報告書の仕様 (ISO 29119-3 + FEW HICCUPPS oracle) | +| `06-pytest-playwright.md` | pytest-playwright fixture / CLI option と NDF 拡張の対応 | + +## 補助スクリプト + +スクリプトの実行は `/ndf:playwright-kit-ops` を参照。計画フェーズで使う主なコマンド: + +```bash +# page role を自動推定 +python scripts/classify_page_role.py --url + +# Playwright codegen で操作を記録 → テストコードに変換 +python scripts/record_scenario.py +``` + +> 上記は `playwright-kit-ops/` ディレクトリ内での実行を想定。 + +## 用語集 + +用語 (accessibility, web vitals, LCP, CLS, TTFB, HAR, trace, overlay, body_check, page role, pwk) は +`docs/README.md` の「用語」節、および playwright_kit ランタイムの README (`playwright-kit-ops/templates/runtime-README.md`) を参照。 + +## 関連 Skill + +- `/ndf:playwright-authoring` — スクリプト作成と実行 (次フェーズ) +- `/ndf:playwright-evidence` — 証跡とレポート +- `/ndf:playwright-kit-ops` — 実行環境の運用 (init_project / スキャン / アップロード) diff --git a/plugins/ndf-shared/skills/playwright-test-planning/docs/01-methodology.md b/plugins/ndf-shared/skills/playwright-planning/docs/01-methodology.md similarity index 100% rename from plugins/ndf-shared/skills/playwright-test-planning/docs/01-methodology.md rename to plugins/ndf-shared/skills/playwright-planning/docs/01-methodology.md diff --git a/plugins/ndf-shared/skills/playwright-test-planning/docs/02-page-roles.md b/plugins/ndf-shared/skills/playwright-planning/docs/02-page-roles.md similarity index 100% rename from plugins/ndf-shared/skills/playwright-test-planning/docs/02-page-roles.md rename to plugins/ndf-shared/skills/playwright-planning/docs/02-page-roles.md diff --git a/plugins/ndf-shared/skills/playwright-test-planning/docs/03-test-techniques.md b/plugins/ndf-shared/skills/playwright-planning/docs/03-test-techniques.md similarity index 100% rename from plugins/ndf-shared/skills/playwright-test-planning/docs/03-test-techniques.md rename to plugins/ndf-shared/skills/playwright-planning/docs/03-test-techniques.md diff --git a/plugins/ndf-shared/skills/playwright-test-planning/docs/04-playwright-mapping.md b/plugins/ndf-shared/skills/playwright-planning/docs/04-playwright-mapping.md similarity index 100% rename from plugins/ndf-shared/skills/playwright-test-planning/docs/04-playwright-mapping.md rename to plugins/ndf-shared/skills/playwright-planning/docs/04-playwright-mapping.md diff --git a/plugins/ndf-shared/skills/playwright-test-planning/docs/05-bug-report.md b/plugins/ndf-shared/skills/playwright-planning/docs/05-bug-report.md similarity index 100% rename from plugins/ndf-shared/skills/playwright-test-planning/docs/05-bug-report.md rename to plugins/ndf-shared/skills/playwright-planning/docs/05-bug-report.md diff --git a/plugins/ndf-shared/skills/playwright-test-planning/docs/06-pytest-playwright.md b/plugins/ndf-shared/skills/playwright-planning/docs/06-pytest-playwright.md similarity index 100% rename from plugins/ndf-shared/skills/playwright-test-planning/docs/06-pytest-playwright.md rename to plugins/ndf-shared/skills/playwright-planning/docs/06-pytest-playwright.md diff --git a/plugins/ndf-shared/skills/playwright-test-planning/docs/README.md b/plugins/ndf-shared/skills/playwright-planning/docs/README.md similarity index 100% rename from plugins/ndf-shared/skills/playwright-test-planning/docs/README.md rename to plugins/ndf-shared/skills/playwright-planning/docs/README.md diff --git a/plugins/ndf-shared/skills/playwright-test-planning/docs/checklists/checklist-auth.md b/plugins/ndf-shared/skills/playwright-planning/docs/checklists/checklist-auth.md similarity index 100% rename from plugins/ndf-shared/skills/playwright-test-planning/docs/checklists/checklist-auth.md rename to plugins/ndf-shared/skills/playwright-planning/docs/checklists/checklist-auth.md diff --git a/plugins/ndf-shared/skills/playwright-test-planning/docs/checklists/checklist-cart-checkout.md b/plugins/ndf-shared/skills/playwright-planning/docs/checklists/checklist-cart-checkout.md similarity index 100% rename from plugins/ndf-shared/skills/playwright-test-planning/docs/checklists/checklist-cart-checkout.md rename to plugins/ndf-shared/skills/playwright-planning/docs/checklists/checklist-cart-checkout.md diff --git a/plugins/ndf-shared/skills/playwright-test-planning/docs/checklists/checklist-common.md b/plugins/ndf-shared/skills/playwright-planning/docs/checklists/checklist-common.md similarity index 100% rename from plugins/ndf-shared/skills/playwright-test-planning/docs/checklists/checklist-common.md rename to plugins/ndf-shared/skills/playwright-planning/docs/checklists/checklist-common.md diff --git a/plugins/ndf-shared/skills/playwright-test-planning/docs/checklists/checklist-dashboard.md b/plugins/ndf-shared/skills/playwright-planning/docs/checklists/checklist-dashboard.md similarity index 100% rename from plugins/ndf-shared/skills/playwright-test-planning/docs/checklists/checklist-dashboard.md rename to plugins/ndf-shared/skills/playwright-planning/docs/checklists/checklist-dashboard.md diff --git a/plugins/ndf-shared/skills/playwright-test-planning/docs/checklists/checklist-edit.md b/plugins/ndf-shared/skills/playwright-planning/docs/checklists/checklist-edit.md similarity index 100% rename from plugins/ndf-shared/skills/playwright-test-planning/docs/checklists/checklist-edit.md rename to plugins/ndf-shared/skills/playwright-planning/docs/checklists/checklist-edit.md diff --git a/plugins/ndf-shared/skills/playwright-test-planning/docs/checklists/checklist-form.md b/plugins/ndf-shared/skills/playwright-planning/docs/checklists/checklist-form.md similarity index 100% rename from plugins/ndf-shared/skills/playwright-test-planning/docs/checklists/checklist-form.md rename to plugins/ndf-shared/skills/playwright-planning/docs/checklists/checklist-form.md diff --git a/plugins/ndf-shared/skills/playwright-test-planning/docs/checklists/checklist-item.md b/plugins/ndf-shared/skills/playwright-planning/docs/checklists/checklist-item.md similarity index 100% rename from plugins/ndf-shared/skills/playwright-test-planning/docs/checklists/checklist-item.md rename to plugins/ndf-shared/skills/playwright-planning/docs/checklists/checklist-item.md diff --git a/plugins/ndf-shared/skills/playwright-test-planning/docs/checklists/checklist-list.md b/plugins/ndf-shared/skills/playwright-planning/docs/checklists/checklist-list.md similarity index 100% rename from plugins/ndf-shared/skills/playwright-test-planning/docs/checklists/checklist-list.md rename to plugins/ndf-shared/skills/playwright-planning/docs/checklists/checklist-list.md diff --git a/plugins/ndf-shared/skills/playwright-test-planning/docs/checklists/checklist-lp.md b/plugins/ndf-shared/skills/playwright-planning/docs/checklists/checklist-lp.md similarity index 100% rename from plugins/ndf-shared/skills/playwright-test-planning/docs/checklists/checklist-lp.md rename to plugins/ndf-shared/skills/playwright-planning/docs/checklists/checklist-lp.md diff --git a/plugins/ndf-shared/skills/playwright-test-planning/docs/checklists/checklist-modal-wizard.md b/plugins/ndf-shared/skills/playwright-planning/docs/checklists/checklist-modal-wizard.md similarity index 100% rename from plugins/ndf-shared/skills/playwright-test-planning/docs/checklists/checklist-modal-wizard.md rename to plugins/ndf-shared/skills/playwright-planning/docs/checklists/checklist-modal-wizard.md diff --git a/plugins/ndf-shared/skills/playwright-test-planning/docs/checklists/checklist-search.md b/plugins/ndf-shared/skills/playwright-planning/docs/checklists/checklist-search.md similarity index 100% rename from plugins/ndf-shared/skills/playwright-test-planning/docs/checklists/checklist-search.md rename to plugins/ndf-shared/skills/playwright-planning/docs/checklists/checklist-search.md diff --git a/plugins/ndf-shared/skills/playwright-report/SKILL.md b/plugins/ndf-shared/skills/playwright-report/SKILL.md deleted file mode 100644 index 2f8897a7..00000000 --- a/plugins/ndf-shared/skills/playwright-report/SKILL.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -name: playwright-report -description: "Generate Playwright test result reports." -when_to_use: "テストレポートの生成 / テスト結果の共有が必要なとき。Triggers: 'テストレポート', 'report.md', 'テスト結果', 'テスト報告書', 'レポート生成', 'テスト結果まとめ'" -allowed-tools: - - Read - - Bash(uv *) - - Bash(pytest *) - - Bash(python *) ---- - -# Playwright Report (レポート生成) - -テスト実行後に **Markdown レポート** を自動生成する。 - -## 自動生成 - -`pytest_terminal_summary` hook で `reports//report.md` が自動生成される。特別な設定は不要。 - -```bash -./scenario-test/run.sh -# → reports//report.md が生成される -``` - -## レポート内容 - -| セクション | 内容 | -|---|---| -| サマリ表 | nodeid, role, page_role, 結果, 実行時間, エラー数 | -| 失敗詳細 | FAIL/ERROR のテストごとの詳細情報 | -| body_check 違反 | PHP/SSR エラー検出の詳細 (URL, パターン, スニペット) | -| エビデンスリンク | video, trace, HAR, screenshot へのパス | - -## レポート設定 - -`scenario.config.yaml` の `report` セクション: - -```yaml -report: - title: "シナリオ E2E テスト 実施報告書" - test_plan_link: "./test-plan.md" - phase_labels: {} -``` - -## Google Drive での共有 - -レポート + エビデンスを Drive にアップロードしてチーム共有する場合は -`/ndf:playwright-evidence-drive` を参照。 - -## 関連 Skill - -- `/ndf:playwright-execution` — テスト実行 + エビデンス収集 -- `/ndf:playwright-evidence-drive` — エビデンス Google Drive 保管・共有 -- `/ndf:playwright-kit-ops` — エビデンスアップロードツール (スクリプト群) -- `/ndf:playwright-scenario-test` — 全機能を統括したフルワークフロー diff --git a/plugins/ndf-shared/skills/playwright-scenario-test/SKILL.md b/plugins/ndf-shared/skills/playwright-scenario-test/SKILL.md deleted file mode 100644 index 3edfc45a..00000000 --- a/plugins/ndf-shared/skills/playwright-scenario-test/SKILL.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -name: playwright-scenario-test -description: "Orchestrate full pytest-playwright scenario testing." -when_to_use: "フル E2E テストワークフロー (計画→スクリプト→実行→レポート) を一貫して行うとき / pytest-playwright 拡張 fixture (pwk_*) の全体像を把握したいとき / init_project.sh でプロジェクトをセットアップするとき。Triggers: 'pytest-playwright', 'pwk_role', 'pwk_evidence', 'init_project', 'シナリオテスト一式', 'フル E2E'" -allowed-tools: - - Read - - Bash(uv *) - - Bash(pytest *) - - Bash(playwright *) - - Bash(python *) ---- - -# Playwright シナリオテスト Skill (v0.6.0) - -Web アプリの E2E シナリオを **理論ベース** で計画し、**再現可能なテストスクリプトを実装してから**、**pytest-playwright** 上でエビデンス動画付きで実行、Markdown レポートを自動生成する一式の Skill。 - -## 大原則 - -1. **再現可能なテストスクリプトを実装してからテストを実施する** -2. **テストスクリプトは ndf plugin 非依存でプロジェクトフォルダに設置する** -3. **テスト実行はエビデンス動画を常に取得する** (オプションで明示的にスキップ可能) - -## フェーズ別 Skill - -| Phase | Skill | 機能 | -|---|---|---| -| 1 | `/ndf:playwright-test-planning` | テスト計画 (HTSM / page role / チェックリスト) | -| 2 | `/ndf:playwright-script-creation` | テストスクリプト作成 (テンプレート→実装→レビュー) | -| 3 | `/ndf:playwright-execution` | テスト実行 + エビデンス収集 (video/trace/overlay/quality) | -| 4 | `/ndf:playwright-report` | レポート生成 (Markdown) | -| -- | `/ndf:playwright-kit-ops` | ツール群 (init_project / スキャン / アップロード) | -| -- | `/ndf:playwright-browser-connect` | ブラウザ接続 (local / CDP remote) | -| -- | `/ndf:playwright-evidence-drive` | エビデンス Google Drive 保管・共有 | - -## 標準ワークフロー - -``` -[Phase 1] テスト計画 (/ndf:playwright-test-planning) - │ 対象 URL → page role 判定 → チェックリスト → テスト技法確定 - ▼ -[Phase 2] スクリプト作成 (/ndf:playwright-script-creation) - │ テンプレート選択 → テストコード実装 → 再現可能性レビュー - │ ※ スクリプトが完成するまでテスト実行に進まない - ▼ -[Phase 3] テスト実行 + エビデンス収集 (/ndf:playwright-execution) - │ 動画デフォルト ON → trace/HAR/overlay/a11y/CWV/body_check - │ ※ --pwk-no-video で動画のみスキップ可 - ▼ -[Phase 4] レポート生成 (/ndf:playwright-report) - │ reports//report.md 自動生成 - ▼ -[任意] ツール群 (/ndf:playwright-kit-ops) - init_project / スキャン / アップロード (任意タイミング) -``` - -## クイックスタート - -1. プロジェクト初期化: `/ndf:playwright-kit-ops` で `./scripts/init_project.sh /path/to/your-app` を実行 -2. 設定編集: `scenario-test/scenario.config.yaml` -3. テストスクリプト作成: `scenario-test/tests/test_*.py` (→ `/ndf:playwright-script-creation`) -4. テスト実行 (動画デフォルト ON): `./scenario-test/run.sh` -5. 動画スキップ: `./scenario-test/run.sh --pwk-no-video` - -→ `your-app/scenario-test/` は ndf plugin 非依存。単体で完結する。 - -## 用語集・制約 - -用語集 (accessibility, web vitals, LCP, CLS, TTFB, HAR, trace, overlay, body_check, page role, pwk) と制約/注意事項は `playwright_kit/` パッケージの README (`templates/runtime-README.md`) および `pyproject.toml` (`templates/pyproject.toml.runtime`) を参照。 diff --git a/plugins/ndf-shared/skills/playwright-script-creation/SKILL.md b/plugins/ndf-shared/skills/playwright-script-creation/SKILL.md deleted file mode 100644 index a42c0a8f..00000000 --- a/plugins/ndf-shared/skills/playwright-script-creation/SKILL.md +++ /dev/null @@ -1,108 +0,0 @@ ---- -name: playwright-script-creation -description: "Create reproducible Playwright E2E test scripts." -when_to_use: "E2E テストスクリプトの作成 / テストコードの実装 / テストテンプレートからのスクリプト生成が必要なとき。Triggers: 'テストスクリプト作成', 'テストコード作成', 'テスト実装', 'テストを書く', 'シナリオ作成', 'codegen', 'テンプレートからテスト', 'playwright codegen'" -allowed-tools: - - Read - - Edit - - Write - - Bash(uv *) - - Bash(playwright *) - - Bash(python *) ---- - -# Playwright Script Creation (テストスクリプト作成) - -再現可能なテストスクリプトを作成し、レビューを経てからテスト実行に進む。 - -## 大原則 - -**テストスクリプトを実装してからテストを実施する。** -スクリプトが完成・レビューを経るまで `/ndf:playwright-execution` に進まない。 - -## 前提条件 - -- テスト計画が完了していること (`/ndf:playwright-test-planning` で計画済み) -- `init_project.sh` でプロジェクトが初期化済みであること (`/ndf:playwright-kit-ops`) - -## ワークフロー - -``` -[A] テスト計画の確認 (チェックリスト / page role / テスト技法) - │ -[B] テンプレート選択 - │ tests/ 配下の test_*.py.template を起点にする - ▼ -[C] テストコード実装 - │ playwright codegen で操作を記録 → テスト関数に組み込む - │ または手動で expect() ベースの assertion を書く - ▼ -[D] 再現可能性レビュー (下記チェックリスト) - │ -[E] テスト実行へ → /ndf:playwright-execution -``` - -## テンプレート一覧 - -`init_project.sh` で以下のテンプレートが `tests/` に配置済み: - -| テンプレート | page role | 内容 | -|---|---|---| -| `test_auth.py` | auth | ログイン / ログアウトフロー | -| `test_list.py` | list | 一覧ページネーション / ソート | -| `test_form.py` | form | 入力 → 送信 → 結果検証 | -| `test_dashboard.py` | dashboard | KPI / リンク遷移 | - -## テストコードの書き方 - -### テンプレートを起点にする - -各 page role のテンプレートが `templates/test_*.py.template` に用意されている。 -`init_project.sh` 実行時に `tests/` へコピーされるので、プロジェクト固有の URL やセレクタを書き換えて使う。 - -→ コード例: `templates/test_form.py.template`, `templates/test_auth.py.template` 等を参照 - -### playwright codegen での操作記録 - -`uv run playwright codegen ` で操作を記録し、生成コードをテスト関数にコピーする。 -コピー後に `@pytest.mark.page_role()`, `@pytest.mark.role()`, `expect()` assertion, `pwk_config.base_url` を追加する。 - -### overlay 付きテスト - -overlay API (`set_caption`, `flash_click`) の使用例は `playwright_kit/overlay.py` を参照。 - -## fixture / marker 一覧 - -fixture / marker の完全な一覧は `playwright_kit/pytest_plugin.py` の `_PWK_MARKERS` 定義と `playwright_kit/fixtures/` 配下の各モジュールを参照。 - -主な fixture: `pwk_config`, `pwk_role_`, `pwk_evidence`, `pwk_accessibility_scan()`, `pwk_web_vitals_measure()` -主な marker: `@pytest.mark.page_role()`, `@pytest.mark.role()`, `@pytest.mark.phase()`, `@pytest.mark.priority()`, `@pytest.mark.no_body_check` - -## 再現可能性レビューチェックリスト - -スクリプト完成後、以下を全項目確認してからテスト実行に進む: - -- [ ] **再現可能性**: 同じ環境で同じ結果が得られるか (ランダム値・タイムスタンプに依存していないか) -- [ ] **テストデータ独立性**: 外部の状態に依存せず、テスト単体で成立するか -- [ ] **marker 付与**: `@pytest.mark.page_role()` が全テスト関数に付与されているか -- [ ] **role marker**: 認証が必要なテストに `@pytest.mark.role()` + `pwk_role_` fixture があるか -- [ ] **assertion 網羅性**: 正常系 + 少なくとも 1 つの異常系 (バリデーション等) が含まれるか -- [ ] **URL 構築**: ハードコードされた URL ではなく `pwk_config.base_url` を使用しているか -- [ ] **wait 戦略**: `wait_until="domcontentloaded"` 等の明示的な待機指定があるか -- [ ] **ndf plugin 非依存**: `scenario-test/` ディレクトリ単体で実行可能か - -## ndf plugin 非依存 - -`init_project.sh` で埋め込まれた `scenario-test/` は: -- `playwright_kit/` パッケージ本体を含む -- `pyproject.toml` で pytest11 entry-point を定義 -- `run.sh` でワンコマンド実行可能 - -→ ndf plugin 未インストール環境でも `./scenario-test/run.sh` で動作する。 - -## 関連 Skill - -- `/ndf:playwright-test-planning` — テスト計画 (前段) -- `/ndf:playwright-execution` — テスト実行 + エビデンス収集 (後段) -- `/ndf:playwright-kit-ops` — init_project / codegen 等のツール群 -- `/ndf:playwright-scenario-test` — 全機能統括 diff --git a/plugins/ndf-shared/skills/playwright-test-planning/SKILL.md b/plugins/ndf-shared/skills/playwright-test-planning/SKILL.md deleted file mode 100644 index a0810adc..00000000 --- a/plugins/ndf-shared/skills/playwright-test-planning/SKILL.md +++ /dev/null @@ -1,97 +0,0 @@ ---- -name: playwright-test-planning -description: "Plan E2E tests and classify page roles." -when_to_use: "E2E テストの計画立案 / page role 分類 / テスト技法の選定 / チェックリスト活用が必要なとき。Triggers: 'テスト計画', 'テスト計画立案', 'page role', 'HTSM', 'ISTQB', 'FEW HICCUPPS', 'チェックリスト', 'テスト技法', 'テスト設計'" -allowed-tools: - - Read - - Bash(python *) ---- - -# E2E テスト計画 (理論ベース) - -HTSM / ISTQB / FEW HICCUPPS に基づいて E2E テストシナリオを計画する。 - -## 計画ワークフロー - -``` -[A] 対象 URL を渡される - │ -[B] page role を判定 → scripts/classify_page_role.py --url - ▼ -[C] 該当チェックリストを開く → docs/checklists/checklist-{role}.md - │ 全項目を「適用」or「不適用 (理由付き)」で判定 - ▼ -[D] 必須テスト技法を確定 → docs/03-test-techniques.md § 11 - ▼ -[E] pytest テストを書く → templates/test_.py.template を起点に - ▼ -[F] スクリプト作成へ → /ndf:playwright-script-creation - テスト計画が確定したら、テストスクリプトの作成に進む。 - テスト計画が完了するまでスクリプト作成には進まない。 -``` - -## page role 一覧 - -| role | 説明 | 例 | -|---|---|---| -| lp | ランディングページ | トップ、LP | -| list | 一覧ページ | 商品一覧、記事一覧 | -| item | 詳細ページ | 商品詳細、記事詳細 | -| edit | 編集ページ | プロフィール編集 | -| form | 申込・入力フォーム | 会員登録、問い合わせ | -| search | 検索ページ | サイト内検索 | -| dashboard | ダッシュボード | 管理画面トップ | -| auth | 認証ページ | ログイン、パスワードリセット | -| cart-checkout | カート・決済 | ショッピングカート | -| modal-wizard | モーダル・ウィザード | ステップ型入力 | - -## チェックリスト - -`playwright-test-planning/docs/checklists/` 配下に role 別チェックリストがある: - -``` -docs/checklists/ -├── checklist-common.md # 全 role 共通項目 -├── checklist-lp.md -├── checklist-list.md -├── checklist-item.md -├── checklist-edit.md -├── checklist-form.md -├── checklist-search.md -├── checklist-dashboard.md -├── checklist-auth.md -├── checklist-cart-checkout.md -└── checklist-modal-wizard.md -``` - -## 方法論ドキュメント - -`playwright-test-planning/docs/` 配下: - -| ファイル | 内容 | -|---|---| -| `01-methodology.md` | HTSM / FEW HICCUPPS / ISO 29119-3 の概要 | -| `02-page-roles.md` | page role 分類の詳細定義 | -| `03-test-techniques.md` | テスト技法 (EP/BVA/Decision Table/Pairwise) + role 必須マッピング | -| `04-playwright-mapping.md` | Playwright API → role / 観点 マッピング | -| `05-bug-report.md` | 不具合報告書の仕様 (ISO 29119-3 + FEW HICCUPPS oracle) | - -## 補助スクリプト - -スクリプトの実行は `/ndf:playwright-kit-ops` skill を参照。主なコマンド: - -```bash -# page role を自動推定 (playwright-kit-ops/scripts/ 配下) -python scripts/classify_page_role.py --url - -# Playwright codegen で操作を記録 → テストコードに変換 -python scripts/record_scenario.py -``` - -> 上記は `playwright-kit-ops/` ディレクトリ内での実行を想定。詳細は `/ndf:playwright-kit-ops` を参照。 - -## 関連 Skill - -- `/ndf:playwright-script-creation` — テストスクリプト作成 (次のフェーズ) -- `/ndf:playwright-execution` — テスト実行 + エビデンス収集 -- `/ndf:playwright-scenario-test` — 全機能を統括したフルワークフロー