# 機能設計書 8-next test

## 概要

本ドキュメントは、Next.jsのテスト実行コマンド `next experimental-test` の機能設計を記述する。Next.jsのテストモード（`next/experimental/testmode`）と連携してE2Eテストを実行するCLIコマンドである。

### 本機能の処理概要

`next experimental-test` コマンドは、Next.jsプロジェクトのE2Eテストをテストランナー（デフォルトはPlaywright）を通じて実行するCLIコマンドである。

**業務上の目的・背景**：Next.jsアプリケーションのE2Eテストを標準化された方法で実行する仕組みを提供する。テストモード（`experimental.testProxy`）との統合により、テスト用のプロキシサーバーを活用したテスト実行が可能になる。

**機能の利用シーン**：Next.jsアプリケーションのE2Eテストを実行する際に使用する。Playwrightテストランナーがデフォルトで使用され、テスト設定が未作成の場合は自動生成される。

**主要な処理内容**：
1. プロジェクトディレクトリの解決と検証
2. Next.js設定の読み込みとテストプロキシ設定の確認
3. テストランナーの決定（CLI > next.config > デフォルト'playwright'）
4. 必要な依存パッケージの確認とインストール
5. Playwright設定ファイルの存在確認と自動生成
6. テストランナーの実行

**関連システム・外部連携**：Playwright（テストランナー）、next/experimental/testmode

**権限による制御**：特段の権限制御はない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 関連画面なし（CLIコンソール出力のみ） |

## 機能種別

CLIコマンド / テスト実行

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| directory | string | No | プロジェクトディレクトリまたはテストランナーへの引数 | パスまたはテストランナー引数として解釈 |
| test-runner-args | string[] | No | テストランナーに渡す追加引数 | なし |
| --test-runner | string | No | テストランナーの指定（デフォルト: playwright） | サポートされたテストランナーであること |

### 入力データソース

- CLI引数
- next.config.js / next.config.ts（`experimental.testProxy`、`experimental.defaultTestRunner`）
- playwright.config.js / playwright.config.ts

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| テスト結果 | text | テストランナーの実行結果 |
| 設定ファイル | file | Playwright設定ファイル（未存在時に自動生成） |

### 出力先

- 標準出力（テスト結果）
- プロジェクトルート（Playwright設定ファイル、自動生成時）

## 処理フロー

### 処理シーケンス

```
1. ディレクトリ引数の解決
   └─ directoryがNext.jsプロジェクトか、テストランナー引数かを判定
   └─ getProjectDirで解決を試みる（失敗時はtestRunnerArgsに振り分け）
2. Next.js設定の読み込み
   └─ loadConfig(PHASE_PRODUCTION_BUILD, baseDir)
   └─ 失敗時はdirectoryをtestRunnerArgsに振り分けて再試行
3. テストランナーの決定
   └─ 優先順位: --test-runner > experimental.defaultTestRunner > 'playwright'
4. experimental.testProxy確認
   └─ 未設定の場合はエラーメッセージを表示して終了
5. テストランナーの実行（Playwright）
   5-1. 必要な依存パッケージの確認（@playwright/test）
   5-2. 未インストール時は自動インストール + playwright install
   5-3. Playwright設定ファイルの存在確認
   5-4. 未存在: TypeScript有無に応じた設定ファイルを自動生成して終了
   5-5. 存在: playwright testコマンドを実行
```

### フローチャート

```mermaid
flowchart TD
    A[next experimental-test 実行] --> B[ディレクトリ解決]
    B --> C[Next.js設定読み込み]
    C --> D[テストランナー決定]
    D --> E{testProxy有効?}
    E -->|No| F[エラー終了]
    E -->|Yes| G{テストランナー種別}
    G -->|playwright| H[依存パッケージチェック]
    G -->|未サポート| I[エラー終了]
    H --> J{パッケージ未インストール?}
    J -->|Yes| K[自動インストール + playwright install]
    J -->|No| L{設定ファイル存在?}
    K --> L
    L -->|No| M[設定ファイル自動生成]
    L -->|Yes| N[playwright test 実行]
    M --> O[メッセージ表示して終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | testProxy必須 | `experimental.testProxy: true`がnext.configに必要 | 常時 |
| BR-02 | テストランナー優先順位 | CLI > next.config.experimental.defaultTestRunner > 'playwright' | テストランナー決定時 |
| BR-03 | directory引数の曖昧性解決 | directoryがNext.jsプロジェクトかテストランナー引数かを段階的に判定 | directory引数指定時 |
| BR-04 | 依存パッケージ自動インストール | @playwright/testが未インストールの場合、自動的にインストールする | Playwright使用時 |
| BR-05 | 設定ファイル自動生成 | playwright.config未存在時にTypeScript/JavaScript設定ファイルを自動生成 | Playwright使用時 |
| BR-06 | サポートテストランナー | 現在サポートされているテストランナーは'playwright'のみ | 常時 |

### 計算ロジック

なし。

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

### 操作別データベース影響一覧

本機能はデータベースを操作しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | testProxy未設定 | experimental.testProxyがtrueでない | next.config.jsに`experimental: { testProxy: true }`を追加 |
| - | 未サポートランナー | 指定されたテストランナーがサポート外 | playwrightを使用 |
| - | 設定読み込み失敗 | baseDirがNext.jsプロジェクトでない | 正しいプロジェクトディレクトリを指定 |

### リトライ仕様

なし。

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

なし。

## パフォーマンス要件

- 依存パッケージの自動インストールは初回のみ発生
- テスト実行時間はテストケースの数と複雑さに依存

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

- 依存パッケージの自動インストールはnpmレジストリからのダウンロードを伴う
- テストプロキシはテスト環境でのみ使用すべき

## 備考

- コマンド名は`next experimental-test`であり、experimentalプレフィックスが付いている
- 現在サポートされているテストランナーはplaywrightのみ（SUPPORTED_TEST_RUNNERS_LIST）
- Playwright設定ファイルの自動生成では`next/experimental/testmode/playwright`からdefineConfigをインポートする
- allowUnknownOptionが設定されており、テストランナーに未知のオプションをパススルーできる

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | next-test.ts | `packages/next/src/cli/next-test.ts` | NextTestOptions型定義（18-20行目）、SupportedTestRunners型（23行目）、requiredPackagesByTestRunner（25-31行目） |

**読解のコツ**: SUPPORTED_TEST_RUNNERS_LISTは`['playwright'] as const`で定義されており、型安全なテストランナー名の管理を実現している。MissingDependency型は依存パッケージの情報（ファイル名、パッケージ名、エクスポート制限）を表す。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | next.ts | `packages/next/src/bin/next.ts` | experimental-testコマンドの定義（495-526行目）。allowUnknownOptionの設定 |
| 2-2 | next-test.ts | `packages/next/src/cli/next-test.ts` | nextTest関数（33-90行目）のメインロジック |

**主要処理フロー**:
1. **45-53行目**: directory引数の曖昧性解決（getProjectDir試行、失敗時はtestRunnerArgsに振り分け）
2. **56-67行目**: Next.js設定の読み込み試行（失敗時はdirectoryをtestRunnerArgsに再振り分け）
3. **70-73行目**: テストランナーの決定（3段階の優先順位）
4. **75-79行目**: testProxy有効確認
5. **82-89行目**: テストランナー別の分岐処理

#### Step 3: Playwright実行処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | next-test.ts | `packages/next/src/cli/next-test.ts` | checkRequiredDeps関数（92-121行目）、runPlaywright関数（123-187行目） |

**主要処理フロー**:
- **92-121行目**: 依存パッケージの確認と自動インストール。playwright installも実行
- **128行目**: 依存パッケージチェックの実行
- **130-135行目**: findUpでplaywright.config.js/tsを検索
- **137-167行目**: 設定ファイル未存在時：TypeScript判定後に設定ファイルを自動生成
- **170-186行目**: 設定ファイル存在時：playwright testを実行

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

```
bin/next.ts (CLIエントリーポイント)
    │
    └─ cli/next-test.ts::nextTest()
           ├─ lib/get-project-dir.ts::getProjectDir()
           ├─ server/config.ts::loadConfig()
           ├─ checkRequiredDeps()
           │      ├─ lib/has-necessary-dependencies.ts::hasNecessaryDependencies()
           │      ├─ lib/install-dependencies.ts::installDependencies()
           │      └─ cross-spawn (playwright install)
           └─ runPlaywright()
                  ├─ findUp(['playwright.config.js', 'playwright.config.ts'])
                  ├─ [設定未存在時]
                  │      ├─ lib/find-pages-dir.ts::findPagesDir()
                  │      ├─ lib/verify-typescript-setup.ts::verifyTypeScriptSetup()
                  │      ├─ defaultPlaywrightConfig() [設定生成]
                  │      └─ writeFileSync() [設定ファイル書き込み]
                  └─ [設定存在時]
                         └─ cross-spawn (playwright test)
```

### データフロー図

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

CLI引数 ─────────────▶ nextTest() ──────────────────▶ テストランナー実行
  (directory, args)         │
                       loadConfig() ────────────────▶ テストランナー決定
                              │
next.config ─────────▶ testProxy確認 ───────────────▶ 有効/エラー
                              │
playwright.config ───▶ runPlaywright() ─────────────▶ テスト結果 (stdout)
  [存在チェック]              │
                       defaultPlaywrightConfig() ──▶ 設定ファイル (fs)
  [未存在時]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| next.ts | `packages/next/src/bin/next.ts` | ソース | CLIメインエントリーポイント |
| next-test.ts | `packages/next/src/cli/next-test.ts` | ソース | next testコマンドのメイン処理 |
| config.ts | `packages/next/src/server/config.ts` | ソース | Next.js設定の読み込み |
| get-project-dir.ts | `packages/next/src/lib/get-project-dir.ts` | ソース | プロジェクトディレクトリ解決 |
| has-necessary-dependencies.ts | `packages/next/src/lib/has-necessary-dependencies.ts` | ソース | 必要な依存パッケージの確認 |
| install-dependencies.ts | `packages/next/src/lib/install-dependencies.ts` | ソース | 依存パッケージの自動インストール |
| find-pages-dir.ts | `packages/next/src/lib/find-pages-dir.ts` | ソース | pages/appディレクトリの検出 |
| verify-typescript-setup.ts | `packages/next/src/lib/verify-typescript-setup.ts` | ソース | TypeScriptセットアップの検証 |
