Revyl Documentation

Tests

Sync tests

Keep local YAML test files and the Revyl server in sync using a git-like workflow. Edit tests locally, push changes upstream, pull updates from teammates, and reconcile test state in one command.

How It Works

Tests live as YAML files in .revyl/tests/. Each file contains a _meta block that tracks the relationship with the remote copy on the Revyl server:

_meta:
    remote_id: a1b2c3d4-5678-90ab-cdef-1234567890ab
    remote_version: 3
    local_version: 3
    last_synced_at: "2026-03-16T10:11:53-07:00"
    checksum: sha256:e3b0c44298fc1c149afbf4c8996fb924...
test:
    metadata:
        name: login-flow
        platform: ios
    build:
        name: ios-test
    blocks:
        - type: instructions
          step_description: Tap Sign In.
FieldPurpose
remote_idUUID linking this file to the server-side test
remote_versionLast known server version at time of sync
local_versionLocal version counter
last_synced_atTimestamp of the last push or pull
checksumSHA-256 of the blocks content; used to detect local edits

When you push, the CLI sends the local blocks to the server and increments the version. When you pull, the CLI downloads the remote blocks and updates the _meta accordingly. Conflicts are detected by comparing version numbers and checksums.


Sync Statuses

Every test has a sync status derived from comparing local _meta against the remote API:

StatusMeaning
syncedLocal and remote are identical
modifiedLocal has unpushed changes (checksum differs from last sync)
outdatedRemote has a newer version than the last pull
conflictBoth local and remote have diverged since the last sync
local-onlyTest exists only in .revyl/tests/, not on the server
remote-onlyTest exists on the server but has no local YAML file
orphanedThe _meta.remote_id points to a test that no longer exists, is inaccessible, or has an invalid ID

revyl test sync -- Test Reconciliation

revyl test sync reconciles local test files with their remote test records in one pass. It does not publish or pull .revyl/config.yaml; use revyl init, revyl config pull, and revyl config push for the project configuration lifecycle.

The root-level revyl sync command remains as a deprecated compatibility alias for revyl test sync. New scripts and documentation should use the canonical test command.

revyl test sync

The sync process for tests:

  1. Name-match linking -- local files that match a remote test by name (but lack a remote_id) are offered for linking.
  2. Import -- remote-only tests with no local counterpart are imported after confirmation (interactive) or skipped (non-interactive / --skip-import).
  3. Status reconciliation -- each linked test is checked and the appropriate action is applied (pull, push, detach, prune).

Flags

FlagDescription
--dry-runPreview planned actions without writing any files
--pruneAuto-prune stale/deleted mappings and orphaned links
--skip-importOnly sync tests already in .revyl/tests/; skip importing remote-only tests
--workflow "Name"Only sync tests belonging to a specific workflow (by name or ID)
--bootstrapInspect local YAML _meta.remote_id links without authentication or writes (useful after cloning a repo)
--non-interactiveDisable prompts; apply deterministic defaults
--interactiveForce interactive prompts (requires TTY stdin)
--jsonOutput results as machine-readable JSON

Examples

revyl test sync                          # Reconcile local and remote tests
revyl test sync --prune                  # Reconcile tests and clean up stale mappings
revyl test sync --workflow "Smoke"       # Only sync tests in the Smoke workflow
revyl test sync --skip-import            # Only sync existing local tests
revyl test sync --dry-run --json         # Preview as JSON (great for CI)
revyl test sync --non-interactive        # No prompts; safe for scripts
revyl test sync --bootstrap              # Inspect local links after cloning a repo

revyl test list -- View Sync Status

Show all local tests with their sync status, local version, and remote version:

revyl test list

Example output:

NAME              STATUS     LOCAL  REMOTE  LAST SYNCED
login-flow        synced     3      3       2 hours ago
checkout-flow     modified   4      3       1 day ago
browse-products   outdated   2      5       3 days ago
signup-flow       local-only 1      -       never

Flags

FlagDescription
--jsonOutput results as JSON

revyl test push -- Push Local Changes

Upload local test changes to the Revyl server.

revyl test push                   # Push all modified tests
revyl test push login-flow        # Push a specific test
revyl test push --force           # Force overwrite remote version
revyl test push --dry-run         # Preview what would be pushed

When pushing, the CLI:

  1. Checks changed local YAML with backend validation.
  2. Resolves build.name to an app_id and any module/script names to UUIDs.
  3. Sends the blocks to the server with an expected_version for optimistic concurrency.
  4. If the remote version has advanced (HTTP 409 conflict), the push is rejected. Use --force to overwrite, or pull first and re-push.
  5. On success, updates _meta with the new remote_version, checksum, and last_synced_at.

What gets synced: blocks, tags, custom variables, environment variables, and device targets.

Flags

FlagDescription
--forceForce overwrite the remote version (bypass conflict detection)
--dry-runShow what would be pushed without pushing

revyl test pull -- Pull Remote Changes

Download test changes from the Revyl server to local YAML.

revyl test pull                   # Pull all tests in local config
revyl test pull login-flow        # Pull a specific test
revyl test pull --all             # Pull ALL org tests, including remote-only
revyl test pull --force           # Force overwrite local changes
revyl test pull --dry-run         # Preview what would be pulled

When pulling, the CLI:

  1. Fetches the remote test and converts tasks to blocks.
  2. Strips server-generated block IDs.
  3. Resolves UUIDs back to human-readable names (modules, scripts).
  4. Pulls associated tags, custom variables, environment variables, and device targets.
  5. Writes the updated YAML with refreshed _meta.

Use --all to discover and import tests created by teammates in the web UI that don't exist locally yet.

Flags

FlagDescription
--allPull all tests from the organization, including those not in local config
--forceForce overwrite local changes
--dry-runShow what would be pulled without pulling

revyl test diff -- Compare Local vs Remote

Show a unified diff between the local and remote versions of a test:

revyl test diff login-flow

Example output:

--- local: login-flow
+++ remote: login-flow
@@ -3,6 +3,7 @@
   - type: instructions
     step_description: Tap Sign In.
   - type: instructions
-    step_description: Type test@example.com in the email field.
+    step_description: Type "{{email}}" in the email field.
+  - type: validation
+    step_description: The dashboard is visible.

revyl test remote -- List All Organization Tests

List every test in your Revyl organization, regardless of local project state:

revyl test remote                      # List all tests
revyl test remote --platform ios       # Filter by platform
revyl test remote --tag regression     # Filter by tag
revyl test remote --limit 20           # Limit results
revyl test remote --json               # JSON output

Flags

FlagDescription
--platform <ios|android>Filter by platform
--tag <name>Filter by tag name
--limit <n>Maximum number of tests to return (default: 50)
--jsonOutput results as JSON

Common Workflows

First-time setup (clone and sync)

After cloning a repository that already has .revyl/tests/ files:

revyl auth login
revyl test sync --bootstrap         # Inspect test links from _meta.remote_id values
revyl test list                     # Verify everything is linked

Import all org tests locally

Pull every test from your org so the full suite is available locally:

revyl test pull --all

Or use the interactive flow:

revyl test sync                     # Will prompt to import each remote-only test

Edit-push-run loop

# 1. Edit a test locally
vim .revyl/tests/login-flow.yaml

# 2. Check what changed
revyl test diff login-flow

# 3. Push the update
revyl test push login-flow

# 4. Run it
revyl test run login-flow

Pull a teammate's changes

revyl test list                     # See which tests are outdated
revyl test pull checkout-flow       # Pull one test
# or
revyl test pull                     # Pull all outdated tests

Resolve a version conflict

When both you and a teammate have changed the same test:

revyl test list                     # Shows "conflict" status
revyl test diff login-flow          # See the remote changes
# Option A: Pull remote, then re-apply your edits
revyl test pull login-flow --force
# Option B: Force-push your version
revyl test push login-flow --force

CI dry-run validation

Check sync status in CI without modifying anything:

revyl test sync --dry-run --json --non-interactive

Parse the JSON output to gate deployments on sync health.

Prune stale mappings

Clean up orphaned links and removed tests:

revyl test sync --prune

Troubleshooting

ProblemFix
"version conflict" on pushSomeone updated the test remotely. Run revyl test pull first, or use --force to overwrite.
Test shows as orphanedThe remote test was deleted or you lost access. Run revyl test sync --prune to detach the link.
"test not found" on pullThe test name doesn't match any remote test. Run revyl test remote to see available tests.
Stale _meta after cloningRun revyl test sync --bootstrap to inspect local _meta.remote_id links, then reconcile normally.
Sync imports too many testsUse --skip-import to only sync tests already in .revyl/tests/, or --workflow "Name" to scope to one workflow.

On this page