Skip to main content

Authentication

Project Setup (Onboarding Wizard)

Running revyl init without flags launches an interactive wizard that walks you through the full setup:
  1. Project Setup — auto-detects your build system (Gradle, Xcode, Expo, Flutter, React Native), creates .revyl/ directory and config.yaml
  2. Authentication — checks for existing credentials; if missing, opens browser-based login
  3. Create Apps — for Expo, automatically creates/links separate app streams per build key (e.g. ios-dev, ios-ci, android-dev, android-ci); for other stacks, select existing apps or create new ones
  4. Dev Loop — detects/configures live reload provider for revyl dev and maps platform_keys to dev streams
  5. First Build — for Expo, defaults to one fast dev-stream upload (ios-dev on macOS, android-dev elsewhere), with easy options for Android-only or parallel both; failures can be retried or deferred without restarting
  6. Create First Test — creates a test; if the name already exists, offers to link, rename, or skip; auto-syncs YAML to .revyl/tests/
Use -y to skip the interactive steps and just generate the config file. During the interactive flow, you can also choose Skip build setup for now. Revyl keeps the detected platform keys as placeholders in .revyl/config.yaml, but clears the build command and artifact path until you are ready to finish native build setup later.

Project Config

View and edit local project settings stored in .revyl/config.yaml.
Supported set keys: open-browser, timeout, hotreload.provider, hotreload.app-scheme, hotreload.port, hotreload.use-exp-prefix.

Running Tests

Advanced Run Flags

Dev Loop

revyl dev starts a local development loop backed by a cloud device session. Both Expo and bare React Native projects are supported, plus native Swift/iOS and Android projects via rebuild-based loops. Each revyl dev invocation creates a dev context — a named, worktree-local dev loop bound to one runtime platform. Use --context for same-repo concurrency; separate worktrees use the default context automatically.
revyl dev:
  • starts your local dev server (Expo via npx expo start --dev-client, or Metro via npx react-native start)
  • creates a Revyl relay to expose it to cloud devices
  • resolves the latest build for your current git branch from your dev app mapping (hotreload.providers.<provider>.platform_keys), then installs it
    • if no branch-matching build exists, it falls back to the latest available build and prints a warning
  • opens a cloud device session wired to the deep link
Normal revyl dev runs suppress advisory HMR diagnostics. Use revyl dev --debug when you specifically need relay/HMR troubleshooting output. In cloud-agent environments, keep the Revyl relay running after Dev loop ready and use device screenshots or revyl device report --session-id <id> --json as source of truth before switching to an external Expo tunnel. For Expo manifest readiness timeouts, use --force-hot-reload as the first diagnostic path. Revyl still starts Expo and verifies relay transport; the flag skips only the manifest and bundle proof so the device can be the source of truth. If the app loads, keep working. If the dev client shows a project load error, restart Expo/Metro or capture a session report with revyl device report --session-id <id> --json. For externally managed Expo tunnels, start Expo yourself and pass either the full dev-client link Expo prints or the raw https://... tunnel URL:
When you pass the full Expo dev-client link, revyl dev uses that link directly and does not require hotreload.providers.expo.app_scheme in .revyl/config.yaml. After the dev loop is running, use revyl device commands to interact:

Device-first flow

Start a plain device session first, then attach and run the dev loop on it:
When a context has an attached session, revyl dev --context <name> reuses it instead of provisioning a new device. Attached sessions are left running when the dev loop exits — use revyl device stop to end them.

Context management

Hot reload providers

Expo deep-links into a dev client via app_scheme; bare React Native loads the JS bundle directly over the Revyl→Metro relay. For provider config schema and the full per-framework setup walkthrough, see Dev Loop Overview.

New Branch Build Flow

Use this when you create a new branch and want revyl dev to run that branch’s build:
If you need to pin exactly one build:

New Branch Direct File Flow (No Build Step)

Use this when you already have a local artifact and want to upload it without running the build command.
  1. Build the artifact with your normal local or CI build command.
  2. Upload it with revyl build upload --file.
  3. Run revyl dev.
Optional explicit version label:
Dev test helpers (pass --context to reuse a running dev loop’s relay):
Plain device sessions (no hot reload — these are the base layer revyl dev builds on):

Builds and Dev Mode

All revyl build and revyl build upload commands push to a shared app container (the app_id in your config). Each upload is tagged with your git branch and commit via metadata. When you run revyl dev, the CLI scans the app container for a build matching your current git branch. If found, it uses that build. If not, it falls back to the latest available build and prints a warning. Each developer gets their own cloud device session, relay, and local dev server — builds are the only shared resource. When you need a new build (by project type):
  • Expo / React Native: Dev mode serves your JS/TS live from your local Metro via a Revyl relay. The binary is just a “dev client shell.” You only need a new build when native dependencies change (new native modules, Podfile changes, Gradle dependency changes, app.json native config).
  • Swift (coming soon): Every code change requires a new build. The binary is the app.
  • Kotlin/Android (coming soon): Every code change requires a new build.
Team workflow commands:
Tip: For Expo/React Native, multiple developers can use the same dev build and still see their own code changes, since JS is served locally. For native projects, each developer should upload their own branch build.

App Management

An app is a named container for your uploaded builds (e.g. “My App Android”). Tests run against an app.

Build Management

Uploading a Build

Use revyl build any time you want to refresh the binary on Revyl without re-running tests. Common flow:
  1. Make sure your app is configured and credentials are available.
  2. Run:
When --version is omitted, the CLI defaults to a branch-aware version label: <branch-slug>-<timestamp> (for example feature-new-login-20260227-153000). In detached-head/non-git contexts it falls back to timestamp-only.
  1. Use the uploaded binary by running tests against the latest upload:
Or let Revyl handle build + upload automatically:
Useful companion commands:
  • revyl build list to verify uploads and inspect platform/app history
  • revyl test run <test> --build-id <id> to pin a specific build
For Expo projects, revyl build performs an EAS auth preflight first. If EAS login is missing, the CLI prompts to run npx --yes eas-cli login (interactive TTY only), or prints the exact fix command in non-interactive environments.

Uploading from a URL

For teams that store builds in internal artifact storage (Artifactory, S3, GCS, GitHub Actions), the CLI can ingest an artifact directly from a URL without downloading it locally first:
The backend downloads, validates, and stores the artifact server-side. The --url flag is mutually exclusive with --file.

Native iOS: Build in Xcode, then revyl dev

For native iOS developers, revyl dev automatically detects the most recent simulator .app from Xcode DerivedData. Build your app in Xcode as you normally would, then run:
The discovery scans ~/Library/Developer/Xcode/DerivedData/<Project>-*/Build/Products/Debug-iphonesimulator/*.app for the most recently modified non-test .app that matches the project in the current directory. Test runner bundles (*Tests.app, *UITests.app) are automatically excluded.

Test Management

For the end-to-end CLI authoring workflow, see Test Configuration.

Test Variables

Per-test variables referenced in step descriptions via {{name}} syntax and substituted at runtime. Names may contain letters, numbers, hyphens, or underscores.
Test variables are distinct from Global Variables (org-wide {{global.name}}) and Global Launch Variables (org-wide reusable launch env vars).

Tags

Organize tests with tags for filtering and grouping.

Module Management

Reusable modules can be imported into tests with module_import blocks. For examples, see Creating Tests.

Scripts

Manage code-execution scripts used by code_execution blocks in tests. Supported runtimes: python, javascript, typescript, bash.

File Management

Manage files (certificates, configs, images, media) in your organization’s file library. Tests reference uploaded files via revyl-file:// URIs.
Supported types (with size limits): certificates .pem .cer .crt .key .p12 .pfx .der (50 MB), config .json .xml .yaml .yml .toml .csv .txt .conf .cfg .ini .properties (50 MB), images .png .jpg .jpeg .gif .pdf (250 MB), media .mp4 .mp3 (500 MB).

Global Resources

Org-wide resources available across all tests.

Global Variables

Shared variables referenced via {{global.name}}. Local test variables with the same name take precedence. Use --secret for credentials or tokens; secret values are encrypted and shown as ******** in list/get output.

Global Launch Variables

Reusable launch variables stored at the org level and attached to tests from the web UI. Use these for shared environment config (API URLs, feature flags) passed at app launch. Getting started with raw device sessions:
Create the org launch variable first with a KEY=VALUE pair, then pass that key (or the launch variable UUID) to revyl device start --launch-var when booting a raw session. Repeat --launch-var to apply multiple launch vars.
Aliases: launch-var, launch-vars, launch-variable.

Workflow Management

Workflow Settings

Stored overrides and run configuration that apply to every execution of a workflow.

Workflow Quarantine

Quarantined tests still run but their failures are ignored when computing overall workflow pass/fail — useful for unblocking CI while flaky tests are investigated.

GitHub PR Automation

Connect the Revyl GitHub App and manage PR automation (pr_review in .revyl/config.yaml) without leaving the terminal.
  • revyl github connect opens the GitHub App install page in your browser, then waits and confirms once the install is active. It’s a no-op if already connected.
  • revyl github push applies your local config immediately (no commit/merge needed). If no pr_review section exists yet, it scaffolds one from the detected build first.
  • The repo’s settings page updates automatically once a push lands.
See the GitHub integration for the full pr_review schema.

Device Management

See Live Observability for the full reference on perf, requests, logs, report --artifact, network, and --device-name presets. For raw device sessions, URL-based app flows work in two modes:
  • revyl device start --app-url ... preinstalls the app before the session is ready.
  • To inject launch config at boot, first create an org launch variable with revyl global launch-var create KEY=VALUE, then pass the key with revyl device start --launch-var KEY.
  • revyl device install --app-url ... installs into an already running raw session.
  • revyl device download-file --url ... only downloads the file to device storage; it does not install the app.

Live Stream URL

Every active session streams the device screen over WebRTC. The --json output from device info and device list includes a whep_url field — a standard WHEP playback URL you can embed in your own platform or feed into any WHEP-compatible player.

Device Session Flags

Shell Completion

Diagnostics & Utilities

Global Flags

These flags are available on all commands: