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

# YAML Test Format

> Schema reference for defining tests as YAML

Tests can be exported as YAML from the [test editor](/tests/creating-tests/test-editor) for version control and CI/CD use, or authored from scratch via the CLI (`revyl test create --from-file my-test.yaml`).

Every block uses an explicit `type:` field plus a `step_description:` payload. The shape is uniform across all step types, which keeps the schema parser-friendly and round-trippable through the editor and CLI.

## Schema

```yaml theme={null}
test:
  metadata:
    name: "Test name"          # required
    platform: "android"        # required: "android" or "ios"
    tags:                      # optional
      - smoke
  build:
    name: "My App"             # required, matches build name in Revyl
    pinned_version: "1.2.0"    # optional, defaults to latest
  blocks:                      # required, array of steps
    - type: instructions
      step_description: "..."
```

The app launches automatically at the start of every test, so you don't need an initial `open_app` step.

## Example

```yaml theme={null}
test:
  metadata:
    name: "Login flow"
    platform: android
  build:
    name: "My App"
  blocks:
    - type: instructions
      step_description: "Type '{{username}}' in the email field"
    - type: instructions
      step_description: "Type '{{password}}' in the password field"
    - type: instructions
      step_description: "Tap the Login button"
    - type: validation
      step_description: "The dashboard screen is visible"
    - type: extraction
      step_description: "Get the welcome message text"
      variable_name: "welcome_msg"
```

## Block Types

| `type:` value | Purpose | Additional fields |
| - | - | - |
| `instructions` | A single user action (tap, type, swipe) | — |
| `validation` | Assert something is visible or true | — |
| `extraction` | Read a value from the screen into a variable | `variable_name` |
| `manual` | Framework-level action (wait, navigate, set\_location, …) | `step_type` + step-specific |
| `if` | Conditional branch | `condition`, `then`, optional `else` |
| `while` | Loop while condition holds | `condition`, `body` |
| `code_execution` | Run a registered script | `script_name` (or inline `code_execution_runtime`) |
| `module_import` | Insert a reusable module's blocks | `module_id` |

Every block also accepts a `step_description:` field — required for all types.

## Manual Steps

The `manual` block runs framework-level actions. The `step_type` field picks which one:

```yaml theme={null}
# Wait for N seconds
- type: manual
  step_type: wait
  step_description: "3"

# Open a specific app (usually unnecessary — the app under test opens automatically)
- type: manual
  step_type: open_app
  step_description: "com.apple.mobilesafari"

# Kill the app under test
- type: manual
  step_type: kill_app

# Go to the home screen
- type: manual
  step_type: go_home

# Navigate to a URL or deep link
- type: manual
  step_type: navigate
  step_description: "myapp://settings"

# Set device GPS location
- type: manual
  step_type: set_location
  step_description: "37.7749,-122.4194"  # latitude,longitude

# Set device appearance
- type: manual
  step_type: set_appearance
  step_description: "dark"               # "light" or "dark"

# Download a file to the device
- type: manual
  step_type: download_file
  step_description: "https://example.com/cert.pem"
```

## Control Flow

```yaml theme={null}
# If / Else
- type: if
  condition: "A login prompt is visible"
  then:
    - type: instructions
      step_description: "Tap 'Sign In'"
  else:
    - type: instructions
      step_description: "Tap 'Continue'"

# While loop
- type: while
  condition: "A 'Load More' button is visible"
  body:
    - type: instructions
      step_description: "Tap 'Load More'"
    - type: manual
      step_type: wait
      step_description: "2"
```

## Modules

Reusable groups of blocks live in modules. Import one by UUID:

```yaml theme={null}
- type: module_import
  step_description: "Login Flow"             # readable label
  module_id: "65c5ac48-b980-43c7-a78e-e58b0daf183b"
```

Use `revyl module list` (CLI) to find module IDs, or `revyl module insert <name>` to print a ready-to-paste snippet.

## Variables

Variables use Mustache-style `{{name}}` syntax. They can be defined up front, extracted at runtime, or pulled from org-level globals via `{{global.name}}`.

```yaml theme={null}
test:
  metadata:
    name: login-flow
    platform: ios
    variables:
      email: test@example.com
      password: TestPass123!
  build:
    name: my-ios-app
  blocks:
    - type: instructions
      step_description: 'Type "{{email}}" in the email field'
    - type: instructions
      step_description: 'Type "{{password}}" in the password field'
```

Variable names allow letters, numbers, hyphens, and underscores. They must not start or end with a hyphen or underscore.

## Validation

The CLI validates YAML before it ever runs:

```bash theme={null}
revyl test validate my-test.yaml
```

That same validator runs automatically during `revyl test create --from-file` and `revyl test push`. It checks: required fields, valid block types, valid manual `step_type` values, platform values, and variable definitions before use.

<Note>
  Authoring tests for AI agents? The full LLM-facing schema (with best
  practices and step-generation guidance) lives in the CLI repo at
  [`internal/schema/yaml_test_schema.go`](https://github.com/RevylAI/revyl-cli/blob/main/internal/schema/yaml_test_schema.go).
</Note>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.