> ## Documentation Index
> Fetch the complete documentation index at: https://docs.therefrain.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# ループ・分岐

> ループでステップを繰り返し、分岐で条件実行します。

## ループ

`loop` 定義を持つステップは、ネストされた `steps` を複数回繰り返します。`while` と `forEach` の2種類のループをサポートしています。

### `while` ループ

条件が truthy の間繰り返します：

```yaml theme={null}
steps:
  - ordinal: 0
    description: "次へボタンがなくなるまでページを処理"
    action:
      type: click
      selector:
        tagName: button
        innerText: "Next"
    url: "https://app.example.com/list"
    riskLevel: low
    requiresConfirmation: false
    loop:
      condition: "{{hasNextPage}}"
      maxIterations: 50
      counterVariable: pageIndex
    steps:
      - ordinal: 0
        description: "現在のページからデータを抽出"
        action:
          type: extract
          script: "document.querySelector('.data').textContent"
        url: "https://app.example.com/list"
        riskLevel: low
        requiresConfirmation: false
        captures:
          - name: hasNextPage
            strategy: evaluate
            expression: "!!document.querySelector('button:has-text(\"Next\")')"
```

### `forEach` ループ

JSON 配列変数またはメモリコレクションのアイテムを反復処理します：

```yaml theme={null}
steps:
  - ordinal: 0
    description: "各ユーザーを処理"
    action:
      type: navigate
      url: "https://app.example.com/users"
    url: "https://app.example.com/users"
    riskLevel: low
    requiresConfirmation: false
    loop:
      forEach: "{{userList}}"
      itemVariable: currentUser
      indexVariable: userIndex
      maxIterations: 100
    steps:
      - ordinal: 0
        description: "ユーザープロフィールに遷移"
        action:
          type: navigate
          url: "https://app.example.com/users/{{currentUser}}"
        url: "https://app.example.com/users/{{currentUser}}"
        riskLevel: low
        requiresConfirmation: false
```

[メモリコレクション](/ja/yaml/memory-operations)を反復処理するには、`collection:` プレフィックスを使用します：

```yaml theme={null}
loop:
  forEach: "collection:products"
  itemVariable: product
```

### ループフィールド

| フィールド             | 型       |  必須  | 説明                                     |
| ----------------- | ------- | :--: | -------------------------------------- |
| `condition`       | string  | いずれか | `while` ループのテンプレート式                    |
| `forEach`         | string  | いずれか | テンプレート変数（JSON 配列）または `collection:name` |
| `itemVariable`    | string  |  No  | 現在のアイテムの変数名（`forEach` のみ）              |
| `indexVariable`   | string  |  No  | 現在のインデックスの変数名（`forEach` のみ）            |
| `maxIterations`   | integer |  No  | 最大反復回数（安全制限）                           |
| `counterVariable` | string  |  No  | ループカウンタの変数名                            |

<Note>
  ループには `condition` と `forEach` のいずれか1つだけを指定する必要があります。両方は不可。
</Note>

## 分岐

`branches` を持つステップは、変数の値に基づいて異なるステップセットを実行します：

```yaml theme={null}
steps:
  - ordinal: 0
    description: "アカウントタイプで分岐"
    action:
      type: navigate
      url: "https://app.example.com/account"
    url: "https://app.example.com/account"
    riskLevel: low
    requiresConfirmation: false
    branches:
      value: "{{accountType}}"
      cases:
        - match: "personal"
          steps:
            - ordinal: 0
              description: "個人フォームに入力"
              action:
                type: input
                value: "{{name}}"
                selector:
                  tagName: input
                  name: "fullName"
              url: "https://app.example.com/account"
              riskLevel: low
              requiresConfirmation: false
        - match: "business"
          steps:
            - ordinal: 0
              description: "法人フォームに入力"
              action:
                type: input
                value: "{{companyName}}"
                selector:
                  tagName: input
                  name: "company"
              url: "https://app.example.com/account"
              riskLevel: low
              requiresConfirmation: false
      default:
        steps:
          - ordinal: 0
            description: "未認識のタイプをスキップ"
            action:
              type: wait
            url: "https://app.example.com/account"
            riskLevel: low
            requiresConfirmation: false
```

### 分岐フィールド

| フィールド     | 型             |  必須 | 説明                    |
| --------- | ------------- | :-: | --------------------- |
| `value`   | string        | Yes | 評価するテンプレート式           |
| `cases`   | BranchCase\[] | Yes | 最低1つのケース              |
| `default` | object        |  No | `steps` 配列を持つデフォルトケース |

### BranchCase フィールド

| フィールド   | 型       |  必須 | 説明                  |
| ------- | ------- | :-: | ------------------- |
| `match` | string  | Yes | マッチする値              |
| `steps` | Step\[] | Yes | マッチ時に実行するステップ（最低1つ） |

## 条件付きステップ

任意のステップに `condition` フィールドを設定できます。条件が falsy に評価されると、ステップはスキップされます：

```yaml theme={null}
steps:
  - ordinal: 0
    description: "合計が0より大きい場合のみ確認をクリック"
    condition: "{{totalAmount}}"
    action:
      type: click
      selector:
        tagName: button
        innerText: "Confirm"
    url: "https://app.example.com/checkout"
    riskLevel: medium
    requiresConfirmation: true
```

<Note>
  1つのステップに `loop` と `branches` を同時に設定することはできません。
</Note>
