# 機能設計書 5-BrowserKit

## 概要

本ドキュメントは、Symfony BrowserKitコンポーネントの機能設計を記述する。BrowserKitはWebブラウザの動作をシミュレートし、プログラムからリクエスト送信やフォーム操作を行う機能を提供する。主にテスト用途で使用される。

### 本機能の処理概要

BrowserKitコンポーネントは、ブラウザの動作（ページ遷移、フォーム送信、リンククリック、Cookie管理、リダイレクトフォロー等）をPHPコードでシミュレートする抽象ブラウザクライアントを提供する。実際のHTTP通信を行うHttpBrowserと、アプリケーション内部で処理を行うKernelBrowser（HttpKernelBrowser）の2つの具象実装が利用可能。

**業務上の目的・背景**：Webアプリケーションのエンドツーエンドテストでは、ブラウザの動作をシミュレートして一連のユーザー操作を自動的に実行する必要がある。BrowserKitは、実際のブラウザを起動することなく高速にWebアプリケーションのテストを実行できる基盤を提供する。

**機能の利用シーン**：機能テスト（WebTestCase）、クローラーベースのスクレイピング、フォーム入力の自動テスト、リダイレクトチェーン検証、Cookie動作テスト等で利用される。

**主要な処理内容**：
1. HTTPリクエストのシミュレート（GET, POST等）
2. レスポンス受信とDomCrawlerによるDOM解析
3. リンククリックのシミュレート
4. フォーム送信のシミュレート
5. Cookie管理（CookieJar）
6. 閲覧履歴管理（History）
7. リダイレクト自動フォロー
8. Meta Refreshリダイレクトフォロー

**関連システム・外部連携**：DomCrawler（レスポンスのDOM解析）、HttpFoundation（Request/Responseオブジェクト）、HttpClient（HttpBrowserでの実際のHTTP通信）、Process（隔離プロセスでのリクエスト実行）

**権限による制御**：BrowserKit自体には権限制御はない。テスト対象アプリケーションの認証機能を通じて認証テストが可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|

BrowserKitは画面機能マッピングに直接関連する画面がない（テスト用途のため）。

## 機能種別

テスト基盤 / ブラウザシミュレーション

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| uri | string | Yes | リクエスト先URI | 有効なURI |
| method | string | No | HTTPメソッド（デフォルト: GET） | 有効なHTTPメソッド |
| parameters | array | No | リクエストパラメータ | - |
| files | array | No | アップロードファイル | - |
| server | array | No | サーバーパラメータ | - |
| content | string | No | リクエストボディ | - |

### 入力データソース

- テストコードからのメソッド呼び出し
- DomCrawlerから取得したLink/Formオブジェクト

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| crawler | Crawler | レスポンスDOMのCrawlerオブジェクト |
| internalResponse | Response | BrowserKit内部のResponseオブジェクト |
| internalRequest | Request | BrowserKit内部のRequestオブジェクト |
| cookieJar | CookieJar | 現在のCookie状態 |

### 出力先

- テストコードへの返却値（Crawlerオブジェクト）

## 処理フロー

### 処理シーケンス

```
1. request()メソッド呼び出し
   └─ URI、メソッド、パラメータを指定
2. Cookie付与
   └─ CookieJarから現在のCookieを取得しリクエストに付与
3. リクエスト実行
   └─ doRequest()（抽象メソッド）による実際のリクエスト処理
4. レスポンス処理
   └─ Cookie更新、履歴記録
5. リダイレクト処理
   └─ followRedirects有効時、自動的にリダイレクト先に遷移
6. Crawler生成
   └─ レスポンスHTMLからCrawlerオブジェクトを生成して返却
```

### フローチャート

```mermaid
flowchart TD
    A[request呼び出し] --> B[CookieJarからCookie取得]
    B --> C[doRequest実行]
    C --> D[Cookie更新]
    D --> E[History記録]
    E --> F{リダイレクト?}
    F -->|Yes| G{followRedirects?}
    G -->|Yes| H{maxRedirects超過?}
    H -->|No| A
    H -->|Yes| I[例外スロー]
    G -->|No| J[Crawler生成]
    F -->|No| J
    J --> K[Crawler返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | リダイレクト自動フォロー | デフォルトでリダイレクトを自動的にフォローする | followRedirects=true（デフォルト） |
| BR-02 | 最大リダイレクト制限 | maxRedirectsを超えるリダイレクトチェーンは例外をスローする | maxRedirectsが設定されている場合 |
| BR-03 | Cookie保持 | CookieJarでリクエスト間のCookieを保持する | 常時 |
| BR-04 | 履歴管理 | Historyで閲覧履歴を管理し、back()/forward()による遷移が可能 | 常時 |

### 計算ロジック

特になし。

## データベース操作仕様

BrowserKitコンポーネントはデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | BadMethodCallException | 不正なメソッド呼び出し | API使用方法の確認 |
| - | InvalidArgumentException | 不正な引数 | 引数の確認 |
| - | LogicException | 不正な操作順序 | 操作フローの確認 |
| - | RuntimeException | リダイレクトループ等の実行時エラー | maxRedirects設定の確認 |

### リトライ仕様

リトライ機能なし。

## トランザクション仕様

トランザクション管理なし。

## パフォーマンス要件

- 実際のブラウザを起動しないため、テスト実行は高速
- KernelBrowser（サーバー内処理）はHTTP通信なしで処理可能

## セキュリティ考慮事項

- テスト用途のため、本番環境での使用は想定していない
- 隔離プロセスモード（insulated）では別プロセスでリクエストを処理

## 備考

- AbstractBrowserは抽象クラスであり、doRequest()メソッドの実装が必要
- HttpBrowser（BrowserKit内）は実際のHTTP通信を行う具象実装
- HttpKernelBrowser（HttpKernel内）はカーネル経由で処理する具象実装

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Request.php | `src/Symfony/Component/BrowserKit/Request.php` | BrowserKit内部のリクエスト表現 |
| 1-2 | Response.php | `src/Symfony/Component/BrowserKit/Response.php` | BrowserKit内部のレスポンス表現 |
| 1-3 | Cookie.php | `src/Symfony/Component/BrowserKit/Cookie.php` | Cookie表現（HttpFoundationのCookieとは別） |
| 1-4 | CookieJar.php | `src/Symfony/Component/BrowserKit/CookieJar.php` | Cookie集合管理 |
| 1-5 | History.php | `src/Symfony/Component/BrowserKit/History.php` | 閲覧履歴管理 |

**読解のコツ**: BrowserKit内のRequest/Response/CookieはHttpFoundationのものとは別クラスであることに注意。BrowserKitはHttpFoundationに依存せず独立して動作できる設計だが、実際にはDomCrawlerとの連携が前提。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AbstractBrowser.php | `src/Symfony/Component/BrowserKit/AbstractBrowser.php` | ブラウザシミュレーションの中核。request(), click(), submit()等 |

**主要処理フロー**:
1. **37行目**: AbstractBrowserクラス定義（ジェネリクス対応テンプレート）
2. **39-58行目**: プロパティ定義（history, cookieJar, server, crawler, followRedirects等）
3. **63-68行目**: コンストラクタ（サーバーパラメータ、History、CookieJar）
4. **73-76行目**: followRedirects()メソッド
5. **97-100行目**: setMaxRedirects()メソッド

#### Step 3: 具象実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | HttpBrowser.php | `src/Symfony/Component/BrowserKit/HttpBrowser.php` | HttpClient経由の実際のHTTP通信 |
| 3-2 | HttpKernelBrowser.php | `src/Symfony/Component/HttpKernel/HttpKernelBrowser.php` | カーネル経由の内部処理 |

### プログラム呼び出し階層図

```
AbstractBrowser::request(method, uri, parameters, files, server, content)
    |
    +-- CookieJar::allValues(uri)  [Cookie取得]
    |
    +-- AbstractBrowser::doRequest(internalRequest) [抽象メソッド]
    |       |
    |       +-- [HttpBrowser] HttpClient::request() [実際のHTTP通信]
    |       +-- [HttpKernelBrowser] HttpKernel::handle() [カーネル処理]
    |
    +-- CookieJar::updateFromSetCookie() [Cookie更新]
    |
    +-- History::add(internalRequest) [履歴記録]
    |
    +-- [リダイレクト時] AbstractBrowser::followRedirect()
    |
    +-- Crawler(responseContent) [Crawler生成・返却]
```

### データフロー図

```
[入力]                        [処理]                              [出力]

URI + Method + Params  --->  AbstractBrowser::request()   --->  Crawler
                              |
                              +-- CookieJar (Cookie付与)
                              +-- doRequest() (HTTP実行)
                              +-- CookieJar (Cookie更新)
                              +-- History (履歴記録)
                              +-- [リダイレクトフォロー]
                              +-- Crawler生成
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AbstractBrowser.php | `src/Symfony/Component/BrowserKit/AbstractBrowser.php` | ソース | ブラウザシミュレーション基底クラス |
| HttpBrowser.php | `src/Symfony/Component/BrowserKit/HttpBrowser.php` | ソース | HTTP通信ベースの具象実装 |
| Request.php | `src/Symfony/Component/BrowserKit/Request.php` | ソース | 内部リクエスト表現 |
| Response.php | `src/Symfony/Component/BrowserKit/Response.php` | ソース | 内部レスポンス表現 |
| Cookie.php | `src/Symfony/Component/BrowserKit/Cookie.php` | ソース | Cookie表現 |
| CookieJar.php | `src/Symfony/Component/BrowserKit/CookieJar.php` | ソース | Cookie管理 |
| History.php | `src/Symfony/Component/BrowserKit/History.php` | ソース | 閲覧履歴管理 |
| Test/ | `src/Symfony/Component/BrowserKit/Test/` | ソース | テストユーティリティ |
| Exception/ | `src/Symfony/Component/BrowserKit/Exception/` | ソース | 例外クラス群 |
