Site search / サイト内検索

必要な情報を探す

ページ内の言葉を探す検索と、意味が近い内容を探す検索を使い分けられます。

「検索する」を実行すると、入力した検索語をOpenAI APIへ送り数値表現に変換し、その数値表現をCloudflare Vectorizeで当サイトの公開情報と照合します。あわせて、Acecore共通検索API(acecore.net)へ送信し、 Acecore関連サイトの公開情報を下部に表示することがあります。個人情報や機密情報は入力しないでください。個人情報の取り扱い

Insights / 技術解説

GitHub Copilot × Playwright でWebサイトをモンキーテストする実践手法

VS Codeのエージェントモード(GitHub Copilot)とPlaywrightブラウザツールを組み合わせ、静的サイトを体系的にモンキーテストした実践記録です。テスト設計の考え方から、実際に発見・修正したバグ、改善提案までを公開します。

  • 技術
  • GitHub Copilot
  • VS Code
  • Astro
  • Webサイト
GitHub Copilot × Playwright でWebサイトをモンキーテストする実践手法
この記事の目次
  1. はじめに
  2. テスト環境
  3. フェーズ1:テスト対象の棚卸し
  4. ソースコード全読み
  5. テスト計画の自動生成
  6. フェーズ2:全ルート巡回テスト
  7. HTTPステータス検証
  8. DOM構造チェック
  9. デッドリンクチェック
  10. フェーズ3:インタラクション検証
  11. FAQ(<details>要素)
  12. 検索モーダル(Pagefind)
  13. YouTubeファサードパターン
  14. コピーボタン(View Transitions後)
  15. ScrollToTopボタン
  16. フェーズ4:SEO・構造化データ監査
  17. OGPメタタグ
  18. 構造化データ(JSON-LD)
  19. サイトマップ
  20. フェーズ5:アクセシビリティ検証
  21. フェーズ6:View Transitions遷移テスト
  22. フェーズ7:セキュリティヘッダー検証
  23. 発見したバグと修正
  24. バグ1:検索モーダルのレジリエンス不足
  25. バグ2:CSPヘッダーのGoogle系オリジン不足
  26. テスト手法の体系化
  27. レイヤー1:静的解析(ソースコード読み取り)
  28. レイヤー2:HTTP層テスト(全ルート巡回)
  29. レイヤー3:DOM層テスト(構造検証)
  30. レイヤー4:インタラクション層テスト(動作検証)
  31. レイヤー5:アクセシビリティ層テスト
  32. 制約と限界
  33. まとめ

はじめに

Webサイトの品質保証は、リリース前の一度きりのチェックでは不十分です。コンテンツの追加、ライブラリの更新、CDN設定の変更など、あらゆるタイミングで予期せぬ不具合が生まれます。

本記事では、VS Code のエージェントモード(GitHub Copilot) がブラウザを直接操作し、サイト全体をモンキーテストした実践記録をまとめます。ソースコードの静的解析からブラウザ上の動的検証まで、AIが一貫して実行したテスト手法を体系化しました。

このテストで見た改善対象は、Astroサイトの品質改善ガイドUX・コード品質編と強くつながっています。


テスト環境

項目 内容
エディタ VS Code + GitHub Copilot(エージェントモード)
AIモデル Claude Opus 4.6
ブラウザ操作 VS Code内蔵Playwrightツール
テスト対象 Astro + UnoCSS + Cloudflare Pages 構成の静的サイト
プレビュー npm run preview(ローカル) + 本番URL

エージェントモードでは、Copilotがターミナルコマンドの実行、ファイルの読み書き、ブラウザの操作を自律的に行います。テスターは「テストしてください」と指示するだけで、AIが以下の全工程を自動実行します。


フェーズ1:テスト対象の棚卸し

ソースコード全読み

AIはまず、プロジェクトのディレクトリ構造を走査し、すべてのコンポーネント・ページ・ユーティリティのソースコードを読み込みます。

src/
├── components/    ← 28コンポーネントを全読み
├── content/blog/  ← 23記事のフロントマターを解析
├── pages/         ← 全ルーティングファイルを把握
├── layouts/       ← BaseLayoutの構造を理解
└── utils/         ← rehypeプラグイン・OG画像生成を確認

この段階でAIは以下を自動的に把握します。

  • 全ルート一覧:静的ページ7件 + ブログ関連ルート(記事・タグ・アーカイブ・著者・ページネーション)
  • インタラクティブ要素:検索モーダル、FAQ開閉、コピーボタン、YouTubeファサード、スクロールトップ、ヒーロースライダー
  • 外部連携:ssgform.com(フォーム)、Cloudflare Turnstile(ボット対策)、Google AdSense、GA4

テスト計画の自動生成

ソースコードの分析結果から、AIはテスト計画をTodoリストとして自動生成します。人間がチェックリストを作る必要はありません。


フェーズ2:全ルート巡回テスト

HTTPステータス検証

ビルド済みサイトをnpm run previewで起動し、Playwrightで全ルートにアクセスします。

テスト対象:38ルート
├── 静的ページ      7件(/, /about/, /services/ など)
├── ブログ記事     23件
├── タグページ     25件
├── アーカイブ      5件
├── ページネーション  2件(/blog/page/2/, /blog/page/3/)
├── 著者ページ      2件
├── RSS            1件
└── 404テスト       1件

結果:全ルート200 OK(意図的404を除く)

DOM構造チェック

各ページで以下を自動検証します。

チェック項目 検証方法 結果
壊れた画像 img.complete && img.naturalWidth === 0 0件
空リンク href が空・#・未設定 0件
unsafe外部リンク target="_blank"rel="noopener" なし 0件
H1の数 document.querySelectorAll('h1').length === 1 全ページOK
スキップリンク 「本文へスキップ」の存在 全ページOK
lang属性 html[lang="ja"] 全ページOK

デッドリンクチェック

起点ページから内部リンクを再帰的に収集し、69件のユニークURLすべての到達を確認。デッドリンクは0件でした。


フェーズ3:インタラクション検証

AIはPlaywrightでブラウザ要素を直接操作し、JavaScriptで動作する機能を検証します。

FAQ(<details>要素)

// AIが実行したテストコードの例
const details = document.querySelectorAll("details");
// 初期状態:すべて閉じている → OK
// クリックで開く → OK
// 再クリックで閉じる → OK

検索モーダル(Pagefind)

  1. window.openSearch() で検索ダイアログを開く
  2. Pagefind UIのロード完了を待機
  3. 「Astro」と入力して検索結果が表示されることを確認
  4. ESCキーで閉じることを確認

YouTubeファサードパターン

  1. .yt-facade 要素をクリック
  2. youtube-nocookie.com/embed/ のiframeが動的に生成されることを確認
  3. autoplay=1 パラメータが付与されていることを確認

コピーボタン(View Transitions後)

View Transitionsでページ遷移したあとに、コードブロックのコピーボタンが再初期化されて動作することを確認。astro:page-loadイベントでの再登録が正しく機能していました。

ScrollToTopボタン

ページ末尾までスクロール → ボタンが表示される → クリック → window.scrollY が0に戻ることを確認。


フェーズ4:SEO・構造化データ監査

OGPメタタグ

全ページで以下を検証しました。

  • og:title / og:description / og:image / og:url / og:type が設定されている
  • twitter:cardsummary_large_image に設定されている
  • canonical URLが正しい
  • OG画像のURLが実在し、推奨サイズ(1200×630)である

構造化データ(JSON-LD)

各ページのJSON-LDを解析し、スキーマの種別と内容を検証しました。

ページタイプ 構造化データ
全ページ共通 Organization, WebSite
ブログ記事 BreadcrumbList, BlogPosting, FAQPage
FAQ付き記事 FAQPage(mainEntityに質問と回答が含まれる)

サイトマップ

sitemap-index.xmlsitemap-0.xml で多言語ページを含む全288URLが登録されていることを確認。robots.txt からサイトマップへの参照も正常でした。


フェーズ5:アクセシビリティ検証

AXEエンジン相当のチェックを、Playwrightで複数ページに対して実行しました。

チェック項目 対象ページ数 違反数
img要素のalt属性 4 0
button要素のラベル 4 0
見出し階層(h1→h2→h3の順序) 4 0
フォームinputのlabel 1(お問い合わせ) 0
ランドマーク要素 4 0
外部リンクのrel属性 4 0
tabindex値の適正 4 0

全4ページ、全チェック項目で違反ゼロという結果でした。


フェーズ6:View Transitions遷移テスト

Astro View Transitionsによるページ遷移では、DOMが差分更新されるためJavaScriptの再初期化が課題になります。以下の遷移パターンを検証しました。

ホーム → ブログ一覧 → 記事 → タグ → 著者 → コンタクト → サービス → ホーム

各遷移後に確認した項目:

  • URL・タイトル・H1が正しく更新される
  • 検索ボタンが動作する
  • コピーボタンが再初期化される
  • パンくずナビが更新される
  • JSエラーがゼロ

フェーズ7:セキュリティヘッダー検証

本番サイトのレスポンスヘッダーを検証した結果:

ヘッダー 評価
Content-Security-Policy フル設定済み
X-Frame-Options SAMEORIGIN
X-Content-Type-Options nosniff
Strict-Transport-Security max-age=15552000
Referrer-Policy strict-origin-when-cross-origin
Permissions-Policy geolocation=(), camera=() 等

発見したバグと修正

今回のテストで2件のバグを発見し、セッション内で修正まで完了しました。

バグ1:検索モーダルのレジリエンス不足

症状:Pagefindスクリプトの読み込みが完了する前に検索ボタンを押すと、UIが応答しない。

原因loadPagefindScript() が一度failしたあと、リトライする仕組みがなかった。

修正:失敗時にPromiseキャッシュをクリアし、ユーザーに「再読み込み」ボタンを表示するフォールバックUIを実装。

バグ2:CSPヘッダーのGoogle系オリジン不足

症状:Google AdSense関連のリソースがCSPでブロックされ、コンソールにエラーが表示される。

原因connect-srcframe-srchttps://www.google.com / https://www.google.co.jp が含まれていなかった。

修正public/_headers のCSPディレクティブにGoogle系オリジンを追加。


テスト手法の体系化

このAIモンキーテストの手法を整理すると、以下のレイヤーに分類できます。

レイヤー1:静的解析(ソースコード読み取り)

  • ディレクトリ構造の走査
  • コンポーネントの依存関係把握
  • フロントマタースキーマ(Zod)の解析
  • CSP・リダイレクト設定の確認

レイヤー2:HTTP層テスト(全ルート巡回)

  • ステータスコード検証(200/404/301)
  • レスポンスヘッダー監査(セキュリティ・キャッシュ)
  • サイトマップ・robots.txt・ads.txt の整合性

レイヤー3:DOM層テスト(構造検証)

  • 壊れた画像・空リンク・unsafe外部リンク
  • H1の一意性・見出し階層
  • メタタグ(OGP・canonical・description)
  • 構造化データ(JSON-LD)

レイヤー4:インタラクション層テスト(動作検証)

  • クリック・入力・キーボード操作
  • モーダル開閉・フォームバリデーション
  • View Transitions後のJS再初期化
  • スクロールイベント・遅延読み込み

レイヤー5:アクセシビリティ層テスト

  • alt属性・ラベル・ARIA
  • 見出し階層・ランドマーク
  • フォーカス管理・tabindex
  • スキップリンク

制約と限界

AIモンキーテストにはいくつかの制約があります。

制約 詳細
ビューポートエミュレーション VS Code内蔵ブラウザではモバイル幅のエミュレーションが効かない。CSSの正当性はビルド出力の静的解析で代替した
ネットワーク状態 オフライン・低速回線のシミュレーションは不可。Service Workerのテストも対象外
ユーザーの「感覚」 デザインの美しさ・読みやすさ・ブランドとの一貫性は人間の判断が必要
認証フロー ログインが必要なページは、認証情報の安全な管理が別途必要

CSSのレスポンシブ対応は、ビルド出力のCSSファイルを直接解析し、@media(min-width:768px) のメディアクエリが正しく生成されていることを確認する方法で代替しました。


まとめ

GitHub Copilotのエージェントモードは、「テストしてください」という一言から、ソースコード分析→テスト計画→ブラウザ自動操作→バグ修正→再検証という一連のQAサイクルを完結させることができます。

今回の実績をまとめると以下のとおりです。

  • テスト対象:38ルート + 25タグ + 5アーカイブ + 2ページネーション = 70ルート
  • テスト項目:HTTPステータス、DOM構造、インタラクション、SEO、アクセシビリティ、セキュリティ、View Transitions
  • 発見バグ:2件(検索モーダル、CSPヘッダー)→ その場で修正
  • アクセシビリティ違反:0件
  • デッドリンク:0件

人間の目視確認とAIの自動検証を組み合わせることで、テストの網羅性と効率を両立できます。

AIモンキーテストの進め方

  1. 棚卸し

    ソースコードを全読みし、テスト対象となるルート・コンポーネント・インタラクションを洗い出す。

  2. 巡回テスト

    全ルートにHTTPリクエストを送り、ステータスコード・壊れた画像・空リンクを検出する。

  3. インタラクション検証

    FAQ開閉・コピーボタン・検索モーダル・YouTube埋め込みなど、JSで動く要素を操作して確認する。

  4. 構造・SEO監査

    構造化データ・OGP・メタタグ・見出し階層・アクセシビリティを全ページで検証する。

手動テストとの比較

従来の手動テスト

  • ブラウザで1ページずつ目視確認
  • チェックリストを手動で作成・管理
  • 確認漏れが発生しやすい
  • 再現手順の記録に時間がかかる

AIモンキーテスト

  • 全ルートを自動巡回してHTTPステータス・DOM構造を検証
  • AIがソースコードからテスト対象を自動抽出
  • 壊れた画像・空リンク・JSエラーをゼロ見落としで検出
  • 発見→原因特定→修正→再検証までをセッション内で完結

よくある質問

GitHub Copilotのエージェントモードは無料で使えますか?

GitHub Copilot Freeプランではエージェントモードの利用に月間の回数制限があります。ProまたはBusinessプランでは制限が緩和されます。VS Code Insiders版で最新機能が先行利用できます。

Playwright以外のブラウザツールでも同じことができますか?

VS Codeの組み込みブラウザツール(Simple Browser + Playwright統合)を使用しています。Copilotがrun_playwright_codeツールでブラウザを直接操作するため、別途Playwrightをインストールする必要はありません。

静的サイト以外にも適用できますか?

はい。SPAやSSRサイトでも同様のアプローチが可能です。ただしログイン認証が必要なページでは、テスト用の認証情報を安全に管理する仕組みが必要です。

テストで見つかったバグの修正もAIに任せられますか?

エージェントモードではファイルの読み書きが可能なため、バグの検出から修正・ビルド確認まで一連の流れをセッション内で完結できます。本記事でも2件のバグを発見し、その場で修正しました。