T-CREATOR

Playwright MCP のエラー解析・デバッグテクニック

Playwright MCP のエラー解析・デバッグテクニック

Playwright MCP でのエラー解析とデバッグは、現代の Web 開発において重要なスキルです。この記事では、実際のエラーケースを通じて効果的なデバッグ手法を学び、より安定したブラウザ自動化を実現する方法を解説します。

背景

Playwright MCP とは何か

Playwright MCP(Model Context Protocol)は、AI エージェントがブラウザ自動化を実行できるようにするプロトコルです。従来のスクリーンショットベースのアプローチと異なり、アクセシビリティツリーを使用して軽量で高速な操作を実現します。

javascript// 基本的な設定例
{
  "mcpServers": {
    "playwright": {
      "command": "npx",
      "args": [
        "@playwright/mcp@latest"
      ]
    }
  }
}

この設定により、AI エージェントは構造化されたデータを通じて Web ページと対話し、視覚的なモデルを必要とせずに確実なツール操作を実現できます。

エラー解析の重要性

Playwright MCP でのエラー解析は、以下の理由で特に重要です:

重要性理由影響
デバッグ効率複雑なブラウザ環境での問題特定開発速度の向上
安定性確保自動化プロセスの信頼性向上プロダクション環境での安定運用
学習コストエラーパターンの理解と対策チーム全体のスキル向上

一般的なエラーパターンの概要

Playwright MCP で発生する主要なエラーパターンを理解することで、迅速な問題解決が可能になります。

エラーの分類

javascript// エラーカテゴリー例
const errorCategories = {
  installation: ['ENOENT', 'E401', 'dependency'],
  connection: ['CDP_WS_ENDPOINT', 'timeout', 'network'],
  browser: ['profile_lock', 'permission', 'headless'],
  mcp: ['server_start', 'client_connect', 'tool_execution'],
};

課題

Playwright MCP でよく発生するエラー

実際の開発現場で頻繁に遭遇するエラーケースを見てみましょう。

認証エラー(E401)

bash# よく見られるエラーメッセージ
2025-06-17 13:50:50.700 [error] user-Playwright: npm error code E401
npm error Incorrect or missing password.

このエラーは、npm レジストリへの認証に失敗した場合に発生します。特に企業環境でのプロキシ設定や認証情報の問題が原因となることが多いです。

Node.js 環境エラー(ENOENT)

bash# spawn npx ENOENT エラー
2025-06-17 13:41:13.890 [info] ight: Starting new stdio process with command: npx @playwright/mcp@latest
2025-06-17 13:41:13.890 [error] ight: Client error for command A system error occurred (spawn npx ENOENT)

このエラーは、システムで npx コマンドが見つからない場合に発生します。Node.js の環境設定や PATH の問題が主な原因です。

ブラウザプロファイルロック

bash# プロファイルロックエラーの例
Error: Could not acquire browser profile lock
SingletonLock file exists: /Users/user/Library/Caches/ms-playwright/mcp-chrome-profile/SingletonLock

デバッグの難しさとその原因

Playwright MCP でのデバッグが困難な理由を整理します:

複雑な依存関係

javascript// 依存関係の例
const dependencies = {
  node: 'Node.js 18+',
  playwright: '@playwright/mcp@latest',
  browser: 'Chromium/Firefox/WebKit',
  mcp_client: 'VS Code/Cursor/Claude Desktop',
};

非同期処理の問題

javascript// 非同期処理でのエラー例
async function debugAsyncIssue() {
  try {
    await page.goto('https://example.com');
    // タイムアウトエラーが発生しやすい箇所
    await page.waitForSelector('.loading', {
      timeout: 5000,
    });
  } catch (error) {
    console.error('非同期処理エラー:', error.message);
  }
}

エラーメッセージの読み方

効果的なエラーメッセージの解析方法を解説します。

ログレベルの理解

javascript// ログレベルの設定例
const logLevels = {
  error: 'クリティカルな問題',
  warn: '警告レベルの問題',
  info: '情報レベルのメッセージ',
  debug: 'デバッグ情報',
};

エラーメッセージの構造

bash# エラーメッセージの構造例
[timestamp] [level] component: error_message
2025-06-17 13:41:13.890 [error] playwright: spawn npx ENOENT
|           |       |           |
時刻       レベル   コンポーネント  エラー内容

解決策

効果的なエラーログの活用法

ログの確認方法

VS Code や Cursor でのログ確認手順:

bash# ログの確認手順
1. View -> Output メニューを開く
2. ドロップダウンから「MCP Logs」を選択
3. エラーメッセージを確認し、パターンを特定

詳細ログの有効化

javascript// 詳細ログ設定
{
  "mcpServers": {
    "playwright": {
      "command": "npx",
      "args": [
        "@playwright/mcp@latest",
        "--debug"
      ]
    }
  }
}

デバッグツールの使い方

Playwright Inspector の活用

javascript// デバッグモードでのPlaywright実行
const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch({
    headless: false, // ヘッドレスモードを無効化
    slowMo: 100, // スローモーション実行
  });
  const page = await browser.newPage();

  // デバッグ用のページ操作
  await page.goto('https://example.com');
  await page.pause(); // 実行を一時停止

  await browser.close();
})();

トレースの取得

javascript// トレース機能の有効化
{
  "mcpServers": {
    "playwright": {
      "command": "npx",
      "args": [
        "@playwright/mcp@latest",
        "--save-trace"
      ]
    }
  }
}

エラーの分類と対処法

システムレベルのエラー対処

bash# Node.js環境の確認
node --version
npm --version

# 必要に応じてNode.jsを更新
# macOSの場合
brew install node

# Windowsの場合
choco install nodejs

認証エラーの解決

bash# npm認証情報の確認
npm whoami

# 必要に応じて再ログイン
npm login

# プロキシ設定が必要な場合
npm config set proxy http://proxy.company.com:8080
npm config set https-proxy http://proxy.company.com:8080

環境変数の設定

javascript// 環境変数設定例
{
  "mcpServers": {
    "playwright": {
      "command": "npx",
      "args": [
        "@playwright/mcp@latest"
      ],
      "env": {
        "PLAYWRIGHT_BROWSERS_PATH": "/custom/path/to/browsers",
        "NODE_OPTIONS": "--max-old-space-size=4096"
      }
    }
  }
}

具体例

セレクタエラーの解析と修正

よくあるセレクタエラー

javascript// 問題のあるセレクタ例
await page.click('#button'); // 要素が見つからない場合

エラーメッセージの例

bashError: Target element not found: #button
  at Page.click (...)
  at async executeClick (...)

修正方法

javascript// より堅牢なセレクタ実装
async function robustClick(page, selector) {
  try {
    // 要素の存在確認
    await page.waitForSelector(selector, { timeout: 5000 });

    // 要素が操作可能かチェック
    const element = await page.$(selector);
    if (!element) {
      throw new Error(`Element not found: ${selector}`);
    }

    // クリック実行
    await element.click();
    console.log(`Successfully clicked: ${selector}`);
  } catch (error) {
    console.error(
      `Click failed for ${selector}:`,
      error.message
    );

    // 代替手段の実行
    await page.evaluate((sel) => {
      const el = document.querySelector(sel);
      if (el) el.click();
    }, selector);
  }
}

アクセシビリティベースの改善

javascript// より良いセレクタ例
const improvedSelectors = {
  // 悪い例
  bad: '#btn-submit',

  // 良い例(アクセシビリティロール使用)
  good: '[role="button"][aria-label="Submit form"]',

  // さらに良い例(テキストベース)
  better: 'text="Submit"',
};

タイムアウトエラーの対処

タイムアウトエラーの分析

javascript// タイムアウトエラーの例
try {
  await page.goto('https://slow-loading-site.com', {
    timeout: 30000,
  });
} catch (error) {
  if (error.name === 'TimeoutError') {
    console.log('ページの読み込みがタイムアウトしました');
  }
}

適応的タイムアウト設定

javascript// 動的タイムアウト設定
class AdaptiveTimeout {
  constructor() {
    this.baseTimeout = 30000; // 基本タイムアウト
    this.fastTimeout = 5000; // 高速操作用
    this.slowTimeout = 60000; // 遅い操作用
  }

  async waitForElement(page, selector, type = 'normal') {
    const timeouts = {
      fast: this.fastTimeout,
      normal: this.baseTimeout,
      slow: this.slowTimeout,
    };

    const timeout = timeouts[type] || this.baseTimeout;

    try {
      await page.waitForSelector(selector, { timeout });
      return true;
    } catch (error) {
      console.error(
        `Timeout waiting for ${selector} (${timeout}ms)`
      );
      return false;
    }
  }
}

ネットワーク状態の監視

javascript// ネットワーク監視付きの操作
async function monitoredNavigation(page, url) {
  const startTime = Date.now();

  // ネットワークリクエスト監視
  page.on('request', (request) => {
    console.log(`Request: ${request.url()}`);
  });

  page.on('response', (response) => {
    console.log(
      `Response: ${response.url()} - ${response.status()}`
    );
  });

  try {
    await page.goto(url, {
      waitUntil: 'networkidle',
      timeout: 30000,
    });

    const loadTime = Date.now() - startTime;
    console.log(`Page loaded in ${loadTime}ms`);
  } catch (error) {
    console.error(`Navigation failed: ${error.message}`);
    throw error;
  }
}

接続エラーのトラブルシューティング

MCP サーバー接続問題

bash# 接続エラーの例
[error] playwright: Failed to connect to MCP server
[error] playwright: Connection timeout after 30000ms

診断スクリプト

javascript// MCP接続診断
async function diagnoseMCPConnection() {
  const diagnostics = {
    nodeVersion: process.version,
    platform: process.platform,
    arch: process.arch,
    env: {
      NODE_PATH: process.env.NODE_PATH,
      PATH: process.env.PATH,
    },
  };

  console.log('System Diagnostics:', diagnostics);

  // Playwright のインストール確認
  try {
    const { chromium } = require('playwright');
    console.log('Playwright is properly installed');

    // ブラウザの起動テスト
    const browser = await chromium.launch({
      headless: true,
    });
    await browser.close();
    console.log('Browser launch test: PASSED');
  } catch (error) {
    console.error(
      'Playwright installation issue:',
      error.message
    );
  }
}

自動回復メカニズム

javascript// 自動回復機能付きの接続
class ResilientMCPConnection {
  constructor(maxRetries = 3) {
    this.maxRetries = maxRetries;
    this.retryCount = 0;
  }

  async connect() {
    while (this.retryCount < this.maxRetries) {
      try {
        await this.attemptConnection();
        console.log('MCP connection established');
        return true;
      } catch (error) {
        this.retryCount++;
        console.error(
          `Connection attempt ${this.retryCount} failed:`,
          error.message
        );

        if (this.retryCount < this.maxRetries) {
          const delay = Math.pow(2, this.retryCount) * 1000; // 指数バックオフ
          console.log(`Retrying in ${delay}ms...`);
          await new Promise((resolve) =>
            setTimeout(resolve, delay)
          );
        }
      }
    }

    throw new Error(
      `Failed to establish MCP connection after ${this.maxRetries} attempts`
    );
  }

  async attemptConnection() {
    // 実際の接続処理
    return new Promise((resolve, reject) => {
      // 接続ロジック
      setTimeout(() => {
        resolve(); // または reject(new Error('Connection failed'))
      }, 1000);
    });
  }
}

環境別の設定例

javascript// 環境別MCP設定
const environments = {
  development: {
    mcpServers: {
      playwright: {
        command: 'npx',
        args: [
          '@playwright/mcp@latest',
          '--headless=false',
          '--slow-mo=100',
        ],
      },
    },
  },

  production: {
    mcpServers: {
      playwright: {
        command: 'npx',
        args: [
          '@playwright/mcp@latest',
          '--headless=true',
          '--no-sandbox',
        ],
      },
    },
  },

  ci: {
    mcpServers: {
      playwright: {
        command: 'docker',
        args: [
          'run',
          '-i',
          '--rm',
          '--init',
          '--pull=always',
          'mcr.microsoft.com/playwright/mcp',
        ],
      },
    },
  },
};

まとめ

Playwright MCP のエラー解析・デバッグテクニックを効果的に活用することで、ブラウザ自動化の品質と信頼性を大幅に向上させることができます。

重要なポイント

  • 系統的なアプローチ: エラーを分類し、適切な対処法を選択する
  • ログの活用: 詳細なログ情報を収集し、問題の根本原因を特定する
  • 予防的措置: 堅牢なエラーハンドリングを実装し、自動回復機能を組み込む
  • 継続的改善: エラーパターンを学習し、より効果的なデバッグ手法を開発する

これらのテクニックを習得することで、Playwright MCP を使用したプロジェクトの成功率を高め、開発効率を大幅に向上させることができます。

今回解説したエラー解析・デバッグテクニックを実際のプロジェクトで活用し、より安定したブラウザ自動化を実現してください。

関連リンク