Skip to main content
Tests can be exported as YAML from the 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

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

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: valuePurposeAdditional fields
instructionsA single user action (tap, type, swipe)
validationAssert something is visible or true
extractionRead a value from the screen into a variablevariable_name
manualFramework-level action (wait, navigate, set_location, …)step_type + step-specific
ifConditional branchcondition, then, optional else
whileLoop while condition holdscondition, body
code_executionRun a registered scriptscript_name (or inline code_execution_runtime)
module_importInsert a reusable module’s blocksmodule_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:
# 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

# 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:
- 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}}.
test:
  metadata:
    name: login-flow
    platform: ios
    variables:
      email: [email protected]
      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:
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.
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.