How it connects
Source access and session preparation
Get the standalone Maestro driver and follow its README to build therevyl-maestro launcher with Java 21 before
loading runtime credentials. There is no package registry release yet.
Repository access is required; contact Revyl support
if you need access.
REVYL_API_KEY through the
runner’s environment or your secret manager. Never put a key into the YAML
flow or command-line arguments. Session ownership is checked by the backend
on attachment and every proxied operation. Text input obtains its session-bound
control connection from the authenticated backend; do not supply a viewer or
worker URL yourself.
Write a supported flow
The sample flow requires an app whose initial screen contains a visibleContinue button. Tapping it must produce the visible text Welcome:
launchApp: the app must already be
running. A saved screenshot is supporting evidence, not a replacement for an
assertion.
From the source package directory, run the built launcher against the exact
session:
--platform ios for an iOS session. This command interacts with a real
device when configured with real credentials. Keep the runner’s exit code in
CI; parse errors, unsupported commands, failed assertions, and transport
failures must fail the job. Keep screenshots private.
Supported native subset
The runner supports hierarchy-backedassertVisible and
assertNotVisible, single selector or coordinate taps, and PNG screenshots.
extendedWaitUntil polls an assertion, while waitForAnimationToEnd performs
a bounded screenshot comparison rather than proving a specific final state.
Assertions use the native accessibility hierarchy, not an independent visual
or occlusion check. Native resource IDs and text can differ between platforms;
adapt selectors rather than assuming an Android ID is an iOS accessibility ID.
Screenshot names must be unique simple names without paths or extensions.
takeScreenshot: smoke writes a private .revyl-maestro/smoke.png file;
existing files are rejected rather than overwritten.
These platform claims concern Android emulators and iOS simulators, not physical
iOS devices. Native flows verified long press, repeated taps, focused deletion,
Enter, Home, appearance changes, and deep links on both platforms, plus Android
Back. Local clipboard commands also ran in those flows.
The complete flow is checked before attachment. The limits are 999 source
commands and 1000 expanded commands, counting each repeated tap or Backspace.
Optional commands, scripts/expressions, hooks, nested flows, general repeat/retry
blocks,
retryTapIfNoChange, and waitUntilVisible are rejected. Unsupported
driver operations also fail explicitly during execution.
Launch is intentionally narrow
Stock Maestro’s default launch stops the app and changes permissions. The current Revyl proxy does not provide that complete lifecycle contract. The only supported form requests neither operation:Text input through the viewer channel
inputText and pasteText use Revyl’s existing manual-input control channel
on Android emulators and iOS simulators. They do not depend on a new focused-input
endpoint or worker capability. pasteText sends the value from an earlier
setClipboard or copyTextFrom; it does not read the device’s OS clipboard.
Literal and dynamically copied input must be nonempty valid Unicode, at most
16 KiB UTF-8. Control characters are rejected except tab, newline, and carriage
return. Passing this validation does not guarantee the device transport supports
every character.
The runner requests input at current focus without clearing or tapping. Android
uses the worker’s text provider; iOS uses its paste path. These are the viewer’s
existing behaviors, not a stronger native text contract:
- Focus and selection: the worker’s
skip_tapoption permits a refocusing fallback when passthrough is unavailable. The adapter does not deliberately tap a field, but cannot guarantee caret or selection preservation on every worker. Focus the intended field before input and assert the resulting value. - Completion: the runner waits for the matching completion acknowledgment, not just receipt. This means the handler returned successfully, not that the app’s field value was verified. A missing, failed, or invalid acknowledgment stops the flow without replaying the input or sending later mutations.
- Viewer interaction: close the live viewer while running a flow with input. A connected viewer’s WebRTC data channel can receive the acknowledgment instead of the runner’s WebSocket. A timeout may mean text was already inserted; inspect the device before rerunning the flow.
- Character support: Android fallback transports have different character limits. iOS input can change the device clipboard, and the pasteboard fallback can show a paste-permission dialog. Unicode validation is not proof of reliable insertion across those paths.
- Privacy: the existing worker input path can log or record typed text. Do not use it for passwords, tokens, or other sensitive content. Adapter diagnostics omit text and control-connection credentials, but cannot change server-side recording behavior.
Deployment-gated gestures
A swipe that ignores Maestro’s requested duration is not an equivalent gesture. The following commands require new worker contracts and authenticated backend relay support. They have offline parser/runtime and installed-launcher coverage, but their successful execution is not verified or enabled on current staging.
Before any flow mutation, authenticated worker health must identify the same
connected workflow and platform and advertise every required capability as
boolean
true. Missing, false, malformed, or unavailable capabilities reject the
whole flow, including taps or launches preceding the gated command. Current
staging checks confirmed that gated swipe flows were rejected with the preceding
tap counter and input value unchanged on both platforms.
Verified clear, app stop/kill/reset,
keychain, permissions, orientation, keyboard dismissal, media, recording, proxy,
airplane mode, AI, and WebView operations also remain unsupported.
Evidence, retries, and cleanup
The adapter adds no HTTP retries, input replay, or Maestro recovery-tap retries. A timeout can still mean an action executed; inspect the device before repeating it. Existing worker-side retry behavior is unchanged, so this is not an end-to-end exactly-once guarantee. Avoid destructive flows and concurrent controllers. The runner only attaches and detaches. It never allocates, installs, resets, or stops the borrowed Revyl session. The job that owns the allocation must release it separately, including after test failures:Next steps
- Prepare an app and session with the device quickstart.
- Compare the Appium driver.
- Check artifact requirements before uploading a build.