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

# Configuration

> Configure visual regression testing with grantiva.yml

## Generate a config file

```bash theme={null}
grantiva init
```

This creates `grantiva.yml` in your project root. The CLI auto-detects your Xcode scheme and workspace.

```bash theme={null}
grantiva init --scheme MyApp --bundle-id com.example.myapp
```

## Configuration reference

```yaml theme={null}
# Required (unless using --app-file)
scheme: MyApp
simulator: iPhone 16

# Optional
workspace: MyApp.xcworkspace    # If using a workspace
project: MyApp.xcodeproj        # If not using a workspace
bundle_id: com.example.myapp    # Derived from binary if --app-file is used

# Screens to capture (VRT)
screens:
  - name: Home
    path: launch

  - name: Profile
    path:
      - tap: "Profile"
      - wait: 1

  - name: Settings
    path:
      - swipe: up
      - tap: "Settings"
      - assert_visible: "Advanced"
      - tap: "Advanced"

# Standalone Maestro flow files to run (functional tests)
flows:
  - grantiva-flows/tasks.yaml
  - grantiva-flows/shopping.yaml

# Diff thresholds
diff:
  threshold: 0.02              # Max pixel diff % (0–1.0)
  perceptual_threshold: 5.0    # Max CIE76 color distance
```

<Note>
  When using `--app-file` to provide a pre-built binary, `scheme` is not required. The bundle ID is derived from the binary's `Info.plist` if not specified.
</Note>

## Screens

Each screen has a `name` and a `path` that describes how to navigate to it.

### Simple launch screenshot

```yaml theme={null}
- name: Home
  path: launch
```

### Navigation steps

```yaml theme={null}
- name: Settings
  path:
    - tap: "Settings"          # Tap by accessibility label
    - type: "search query"     # Type into focused field
    - wait: 2                  # Wait N seconds
    - swipe: up                # up, down, left, right
    - assert_visible: "Advanced" # Fail if element not visible
    - tap: "Advanced"
```

| Action                        | Description                                         |
| ----------------------------- | --------------------------------------------------- |
| `launch`                      | Screenshot immediately after app launch             |
| `tap: "Label"`                | Tap element by accessibility label                  |
| `type: "text"`                | Type text into the focused field                    |
| `swipe: direction`            | Swipe up, down, left, or right                      |
| `wait: N`                     | Wait N seconds                                      |
| `assert_visible: "Label"`     | Verify element is visible (fails the screen if not) |
| `assert_not_visible: "Label"` | Verify element is not visible                       |
| `run_flow: "path.yaml"`       | Include steps from another YAML file                |

A screenshot is automatically taken at the end of each screen's path.

## Flows

The `flows:` key lists paths to existing Maestro YAML files that `grantiva run` executes as standalone functional tests, in addition to any `screens:` entries.

```yaml theme={null}
flows:
  - grantiva-flows/tasks.yaml
  - grantiva-flows/shopping.yaml
  - grantiva-flows/calendar.yaml
```

**How it differs from `screens:`**

|            | `screens:`                                             | `flows:`                                      |
| ---------- | ------------------------------------------------------ | --------------------------------------------- |
| Format     | Grantiva DSL                                           | Native Maestro YAML                           |
| Purpose    | VRT capture targets                                    | Functional / smoke tests                      |
| Screenshot | Taken automatically at the end                         | Wherever `takeScreenshot` appears in the file |
| Baselines  | Compared against stored baselines by `grantiva ci run` | Not compared — pass/fail only                 |

Paths are resolved relative to the directory containing `grantiva.yml`. Any screenshots taken inside a flow file are saved to `.grantiva/captures/` named `<flowname>-<screenshot>.png`.

`grantiva run` runs all `screens:` first, then each flow in `flows:` order. A runner failure in any flow captures a `simctl` screenshot of the current simulator state for debugging.

<Note>
  `flows:` is only used by `grantiva run`. The `grantiva ci run` pipeline (VRT) only processes `screens:`.
</Note>

## Maestro compatibility

Grantiva can read [Maestro](https://maestro.mobile.dev) flow files as a drop-in replacement. If you have existing Maestro flows, there's no need to rewrite them.

### Auto-detection

Grantiva auto-detects the format when loading configuration:

1. Looks for `grantiva.yml` — parses as Grantiva or Maestro format (auto-detected)
2. If no `grantiva.yml`, looks for a `.maestro/` directory and loads all flow files

### Using Maestro flows

Write `grantiva.yml` in Maestro format, or place flows in `.maestro/`:

```yaml theme={null}
appId: com.example.myapp
---
- launchApp
- tapOn: "Sign In"
- inputText: "user@example.com"
- takeScreenshot: "Login"
- tapOn: "Submit"
- assertVisible: "Welcome"
- takeScreenshot: "Welcome"
```

Each `takeScreenshot` becomes a named screen capture point. Commands between screenshots become navigation steps.

### Supported Maestro commands

| Maestro command                         | Grantiva mapping                             |
| --------------------------------------- | -------------------------------------------- |
| `tapOn` / `doubleTapOn` / `longPressOn` | `tap` (supports `text:` and `id:` selectors) |
| `inputText`                             | `type`                                       |
| `assertVisible`                         | `assert_visible`                             |
| `assertNotVisible`                      | `assert_not_visible`                         |
| `scroll: {direction: down}`             | `swipe: up` (direction inverted)             |
| `swipe: {start: ..., end: ...}`         | `swipe` (direction derived from coordinates) |
| `runFlow` / `runFlow: {file: ...}`      | `run_flow`                                   |
| `extendedWaitUntil: {text: ...}`        | `assert_visible`                             |
| `waitForAnimationToEnd`                 | `wait` (timeout converted to seconds)        |
| `takeScreenshot: "name"`                | Screen capture boundary                      |
| `launchApp` / `stopApp`                 | Skipped (Grantiva handles app lifecycle)     |

Unsupported commands (`pressKey`, `setPermissions`, `evalScript`, `repeat`, etc.) are silently skipped.

### Sub-flows

Maestro sub-flows referenced via `runFlow` are also parsed in Maestro format when auto-detected. You can mix Grantiva and Maestro flow files.

## Diff thresholds

| Setting                | Default | Description                              |
| ---------------------- | ------- | ---------------------------------------- |
| `threshold`            | `0.02`  | Maximum pixel difference percentage (2%) |
| `perceptual_threshold` | `5.0`   | Maximum CIE76 perceptual color distance  |

A screen fails if either threshold is exceeded.

## Build settings

Pass extra flags directly to `xcodebuild`:

```yaml theme={null}
build_settings:
  - "OTHER_SWIFT_FLAGS=-DDEBUG_MODE"
  - "SWIFT_OPTIMIZATION_LEVEL=-Onone"
```

Each entry is appended verbatim to the xcodebuild invocation.

## Accessibility checks

```yaml theme={null}
a11y:
  fail_on_new_violations: true        # Fail the run on new violations (default: true)
  rules:
    - missing_label                   # Elements with no accessibility label
    - small_tap_target                # Tap targets smaller than 44×44pt
```

| Setting                  | Default                             | Description                              |
| ------------------------ | ----------------------------------- | ---------------------------------------- |
| `fail_on_new_violations` | `true`                              | Fail CI when new violations are detected |
| `rules`                  | `[missing_label, small_tap_target]` | Which a11y rules to enforce              |

## Size limits

Warn or fail when a screenshot exceeds a file size threshold:

```yaml theme={null}
size:
  warn_mb: 0.5    # Warn if any capture exceeds 500 KB (default: 0.5)
  fail_mb: 2.0    # Fail if any capture exceeds 2 MB (default: 2.0)
```

## AI provider

```yaml theme={null}
ai:
  provider: none    # AI provider for smart assertions (default: none)
```

Reserved for future AI-powered visual assertion features.

## Directory structure

After running commands, Grantiva creates:

```
.grantiva/
├── captures/          # Screenshots from capture runs
│   └── diffs/         # Diff images for failed comparisons
└── baselines/         # Local baseline images (if not using cloud)
```

Credentials are stored at `~/.grantiva/auth.json`.
