開発者ツール:Codegen、トレースビューアー、MCP サーバー
前提知識
- ›第 1〜4 回:コアアーキテクチャの十分な理解
- ›ブラウザの DevTools に関する基本的な知識
開発者ツール:Codegen、トレースビューアー、MCP サーバー
これまでのシリーズでは、Playwright のコアアーキテクチャを丁寧に解剖してきました。クライアントとサーバーの分離、プロトコル層、ブラウザ抽象化、セレクターエンジン、テストランナーと、各層を順に掘り下げてきました。最終回となる本稿では、それらすべての層の上に乗っかる開発者ツールを概観します。コード生成システム、レコーダー、トレースビューアー、そして最新の追加機能である MCP サーバー(AI エージェントに Playwright を公開するしくみ)です。これらのツールには共通の調整ポイントがあり、これまで見てきたアーキテクチャパターンの上に成り立っています。
コード生成と言語エミッター
Playwright の codegen コマンドは、ユーザーの操作を記録し、複数の言語でテストコードを生成します。コード生成システムは packages/playwright-core/src/server/codegen/ に置かれており、すっきりとした抽象化パターンに従っています。
packages/playwright-core/src/server/codegen/language.ts#L22-L28 の generateCode() 関数は、記録されたアクションと言語ジェネレーターを受け取り、構造化された出力を返します。
export function generateCode(actions: ActionInContext[], languageGenerator: LanguageGenerator, options: LanguageGeneratorOptions) {
const header = languageGenerator.generateHeader(options);
const footer = languageGenerator.generateFooter(options.saveStorage);
const actionTexts = actions.map(a => generateActionText(languageGenerator, a, !!options.generateAutoExpect))
.filter(Boolean) as string[];
const text = [header, ...actionTexts, footer].join('\n');
return { header, footer, actionTexts, text };
}
./types からインポートされる LanguageGenerator インターフェースは、各言語が実装すべき契約を定義しています。
generateHeader(options)— import 文、ブラウザ起動、コンテキストのセットアップgenerateAction(action)— 記録されたアクションをその言語らしいコードに変換generateFooter(saveStorage)— 後処理、ブラウザのクローズ
サポートされている各言語には専用のジェネレーターが用意されています。JavaScript、Python、C#、Java のほか、playwright-test(生の script ではなく test() ブロックを生成)、python-pytest、csharp-mstest、csharp-nunit、java-junit などのバリアントも存在します。
flowchart TD
A["User Action<br/>(click, type, navigate)"] --> B["Recorder captures action"]
B --> C["ActionInContext"]
C --> D{"Language Generator"}
D -->|JavaScript| E["await page.click('.btn')"]
D -->|Python| F["await page.click('.btn')"]
D -->|C#| G["await page.ClickAsync('.btn')"]
D -->|Java| H["page.click('.btn')"]
D -->|Playwright Test| I["test('...', async ({page}) =>\n await page.click('.btn'))"]
packages/playwright-core/src/server/codegen/language.ts#L30-L50 の generateActionText() ヘルパーは、auto-expect の生成も担っています。これを有効にすると、各アクションの前に assertVisible チェックが差し込まれ、より堅牢なテストコードが生成されます。
ヒント:
npx playwright codegen --target=playwright-testを使うと、テストランナーの fixture システムを直接活用したコードが生成されます。デフォルトの JavaScript ターゲットよりも、よりイディオマティックなテストコードが得られます。
レコーダーのアーキテクチャ
レコーダーは、ブラウザウィンドウ上でユーザーの操作をキャプチャし、コード生成システムに渡す対話的なレイヤーです。その調整役となるのが、packages/playwright-core/src/server/debugController.ts#L36-L57 にある DebugController クラスです。
export class DebugController extends SdkObject {
static Events = {
StateChanged: 'stateChanged',
InspectRequested: 'inspectRequested',
SourceChanged: 'sourceChanged',
Paused: 'paused',
SetModeRequested: 'setModeRequested',
};
private _playwright: Playwright;
_sdkLanguage: Language = 'javascript';
DebugController は、記録・インスペクト・デバッグといったすべての開発者ツールモードの中心的な調整役です。第 3 回で扱った Instrumentation システムを使ってブラウザイベントを監視し、それをレコーダーのアクションに変換します。
レコーダー自体は注入される UI コンポーネントを持っています。packages/recorder/ パッケージで構築された Web アプリケーションで、ブラウザにオーバーレイとして注入され、サーバーサイドのレコーダーロジックと通信します。codegen 実行中に表示される「Record」「Pick Locator」「Assert」ボタンのついたフローティングツールバーが、まさにこのレコーダー UI です。
sequenceDiagram
participant User as User Browser Actions
participant RUI as Recorder UI (Injected)
participant Rec as Recorder (Server)
participant DC as DebugController
participant CG as Code Generator
User->>Rec: Click intercepted
Rec->>Rec: Create ActionInContext
Rec->>DC: Action recorded
DC->>CG: generateCode(actions)
CG-->>DC: Generated source
DC->>RUI: SourceChanged event
RUI->>RUI: Update code display
DebugController は生成コードが変わるたびに SourceChanged イベントを発行し、レコーダー UI はそれを受け取ってテストスクリプトをリアルタイムに更新します。
トレースシステム:記録と閲覧
Playwright のトレースシステムは、テスト実行の全記録をキャプチャします。すべてのアクション、DOM スナップショット、ネットワークリクエスト、コンソールログ、スクリーンショットがまとめて .zip 形式のトレースファイルに束ねられ、スタンドアロンのトレースビューアーで閲覧できます。
記録
トレースレコーダーは packages/playwright-core/src/server/trace/recorder/ に置かれており、第 3 回で掘り下げた Instrumentation インターフェースに接続します。
onBeforeCall/onAfterCall— タイミングとパラメーターを含むアクションのキャプチャonPageOpen/onPageClose— ページのライフサイクル追跡- ネットワークインターセプター — リクエスト・レスポンスデータのキャプチャ
DOM スナップショットについては、第 4 回で扱った注入スクリプトのアーキテクチャを使い、各アクションの前後といった重要なタイミングでページの DOM 状態をシリアライズします。
閲覧
packages/trace-viewer/ にあるトレースビューアーは、トレースファイルを読み込んでインタラクティブなタイムラインを表示するスタンドアロン Web アプリケーションです。ブラウザ自動化のタイムトラベルデバッガーと呼べるほど、Playwright の中でも特に印象的な機能のひとつです。
flowchart LR
subgraph "During Test"
A["Instrumentation Hooks"] --> B["Trace Recorder"]
B --> C["Actions + Snapshots + Network"]
C --> D["trace.zip"]
end
subgraph "After Test"
D --> E["Trace Viewer Web App"]
E --> F["Action Timeline"]
E --> G["DOM Snapshot Viewer"]
E --> H["Network Log"]
E --> I["Console Log"]
end
トレースは npx playwright show-trace trace.zip で開けるほか、HTML レポーターに直接埋め込まれる形でも確認できます。show-trace コマンドはコア CLI に登録されています。
MCP サーバー:AI エージェントのための Playwright
Playwright のツールエコシステムに最近加わったのが、Model Context Protocol(MCP)サーバーです。これは Playwright をツールサーバーとして AI エージェントに公開するしくみで、packages/playwright-core/src/tools/mcp/ に実装されています。
MCP サーバーのエントリーポイントは packages/playwright-core/src/tools/mcp/index.ts#L30-L46 にあります。
export async function createConnection(userConfig: Config = {}, contextGetter?: () => Promise<BrowserContext>): Promise<Server> {
const config = await resolveConfig(userConfig);
const tools = filteredTools(config);
const backendFactory: ServerBackendFactory = {
name: 'api',
toolSchemas: tools.map(tool => tool.schema),
create: async (clientInfo: ClientInfo) => {
const browser = contextGetter ? new SimpleBrowser(await contextGetter()) : await createBrowser(config, clientInfo);
const context = config.browser.isolated ? await browser.newContext(config.browser.contextOptions) : browser.contexts()[0];
return new BrowserBackend(config, context, tools);
},
};
return createServer('api', packageJSON.version, backendFactory, false);
}
これにより、MCP 準拠のサーバーが構築され、ナビゲート・クリック・スクリーンショット・フォーム入力・ページコンテンツの読み取りなど、30 以上のブラウザ自動化ツールが公開されます。各ツールは JSON スキーマで定義され、Playwright の標準的なブラウザ自動化 API を使うハンドラーとして実装されています。
packages/playwright-core/src/tools/mcp/program.ts#L33-L60 の CLI エントリーポイントを見ると、豊富な設定オプションが確認できます。
export function decorateMCPCommand(command: Command) {
command
.option('--browser <browser>', 'browser or chrome channel to use')
.option('--caps <caps>', 'additional capabilities: vision, pdf, devtools')
.option('--cdp-endpoint <endpoint>', 'CDP endpoint to connect to')
.option('--headless', 'run browser in headless mode')
.option('--isolated', 'keep browser profile in memory')
// ... 20+ more options
flowchart TD
AI["AI Agent<br/>(Claude, GPT, etc.)"] -->|"MCP Protocol"| MCP["Playwright MCP Server"]
MCP --> BB["BrowserBackend"]
BB --> T1["navigate tool"]
BB --> T2["click tool"]
BB --> T3["screenshot tool"]
BB --> T4["fill tool"]
BB --> T5["30+ more tools..."]
T1 --> PW["Playwright API"]
T2 --> PW
T3 --> PW
PW --> Browser["Browser"]
MCP サーバーは、ローカルのツール統合向けの stdio と、リモート接続向けの SSE/StreamableHTTP の両トランスポートをサポートしています。また、--extension オプションを使えば、すでに起動済みのブラウザに接続する Chrome 拡張機能モードも利用できます。
ヒント:
npx playwright mcp --headlessを実行すると、AI エージェントが接続できる Playwright MCP サーバーが起動します。--caps visionを追加すると、スクリーンショットベースのビジュアル理解が有効になります。
CLI のアーキテクチャ
Playwright の CLI は、全体的なアーキテクチャを反映して 2 つのパッケージに分かれています。
コア CLI
packages/playwright-core/src/cli/program.ts#L31-L68 にあるコア CLI は、playwright-core 単体で動作するコマンドを登録します。
open [url]— 手動テスト用にブラウザを起動codegen [url]— 操作を記録してコードを生成install [browser...]— ブラウザのバイナリをダウンロードshow-trace— トレースビューアーを開く
これらのコマンドは Commander.js を使って登録されており、起動時間を抑えるために遅延 import(await import('./browserActions'))を活用しています。
テストランナー CLI
packages/playwright/src/program.ts#L33-L57 にあるテストランナー CLI は、コア CLI をインポートしてテスト固有のコマンドを追加することで、コア CLI を拡張します。
import { program } from 'playwright-core/lib/cli/program';
function addTestCommand(program: Command) {
const command = program.command('test [test-filter...]');
command.description('run tests with Playwright Test');
// ... options
}
npx playwright test と npx playwright codegen が同じ playwright コマンドから使えるのはこのためです。playwright パッケージはコア CLI を再エクスポートしつつ、その上に独自のコマンドを追加しています。
flowchart TD
subgraph "playwright-core CLI"
O["open"]
CG["codegen"]
IN["install"]
ST["show-trace"]
MCP2["mcp"]
end
subgraph "playwright CLI (extends core)"
T["test"]
SR["show-report"]
MC["merge-reports"]
end
CLI["npx playwright"] --> T
CLI --> O
CLI --> CG
CLI --> IN
CLI --> ST
CLI --> MCP2
CLI --> SR
CLI --> MC
シリーズのまとめ
全 6 回にわたって、Playwright のトップレベルの monorepo 構造からすべての主要な層まで、アーキテクチャを追いかけてきました。
- アーキテクチャ概観 — monorepo、クライアントとサーバーの分離、DEPS.list の境界、エントリーポイント
- プロトコル層 — ChannelOwner、Connection、Dispatcher、オブジェクトのライフサイクル、バリデーション
- ブラウザ抽象化 — BrowserType の階層、PageDelegate、CDP、instrumentation
- DOM 操作 — 注入スクリプト、セレクターエンジン、Locator、自動待機
- テストランナー — マルチプロセス調整、fixture の DAG、タスクパイプライン、reporter
- 開発者ツール — Codegen、レコーダー、トレースビューアー、MCP サーバー、CLI
繰り返し登場するテーマは、関心の分離(クライアント vs サーバー、汎用 vs ブラウザ固有)、プロトコル駆動設計(YAML → 生成された型 → 検証済みメッセージ)、そしてコンポーザビリティ(fixture、セレクターのチェーン、reporter の多重化)です。これらのパターンがあるからこそ、Playwright は 22 パッケージの monorepo として保守しやすく、AI エージェント統合といった新しいユースケースへの拡張性も保たれています。
Playwright にコントリビュートする場合も、その上にツールを構築する場合も、あるいは単にテストの動作を深く理解したい場合にも、このアーキテクチャの知識がコードベースを自信を持って読み解くための地図になるはずです。