Skip to main content

Mobile Test YAML

Mobile tests use the same YAML shape as UI tests, with mobile-specific actions and selectors. Same steps list, same {{variable}} substitution rules, same assertion patterns.

Minimal example

steps:
- action: tap
selector: accessibility:test-Username
- action: type
selector: accessibility:test-Username
value: standard_user
- action: tap
selector: accessibility:test-Password
- action: type
selector: accessibility:test-Password
value: secret_sauce
- action: tap
selector: accessibility:test-LOGIN
- action: assert_visible
selector: accessibility:test-PRODUCTS

Selectors

Mobile uses Appium's selector syntax — same as Appium docs.

PrefixMeansExample
accessibility:Accessibility ID (preferred)accessibility:test-Username
id:Native resource id (Android) / accessibility id (iOS)id:com.example:id/username
xpath:XPathxpath://*[@text='Login']
class:Class nameclass:android.widget.Button
predicate:iOS NSPredicatepredicate:label == 'Login'

Always prefer accessibility IDs — they're stable across UI redesigns and work the same on Android + iOS when developers tag elements correctly.

Actions

ActionWhat it doesRequired fields
tapTap the elementselector
typeType text into a field (tap first if not focused)selector, value
swipeSwipe gesturedirection (up/down/left/right)
long_pressPress-and-holdselector, duration (ms, default 1000)
waitPause for a fixed durationduration (ms)
wait_forWait until element appears (with timeout)selector, timeout (ms, default 10000)
backAndroid back button / iOS swipe-back
homeSend app to background
assert_visibleFail if element not on screenselector
assert_textAssert element's text matchesselector, expectedText
assert_not_visibleFail if element IS on screenselector
screenshotCapture screen (auto-attached to result)optional name
scroll_toScroll until element is visibleselector
clearClear a text fieldselector

value vs expectedText

Consistent with UI testing:

  • value — data for input actions (type, select)
  • expectedText — assertion text for validation actions (assert_text)

assert_text uses contains matching (not equals). For exact match, use assert_text_equals (if available) or scope the selector tighter.

Direction values for swipe

up, down, left, right. Optionally percent (0-100, default 75) controls how much of the screen to swipe.

- action: swipe
direction: down
percent: 50

Variables

Same {{variable}} and ${variable} syntax as the rest of the platform (powered by Apache Commons Text StringSubstitutor).

steps:
- action: type
selector: accessibility:test-Username
value: "{{username}}"
- action: type
selector: accessibility:test-Password
value: "{{password}}"

Values come from the environment's auth config or per-test variables. Never hardcode credentials in the YAML — see Credentials.

Capabilities

The platform builds the Appium capability dict from the mobile-app's config + the device tier. You can extend it via:

Per-app extra capabilities

In the mobile app's config (UI: Mobile Apps → Edit → Appium Capabilities):

{
"appium:autoGrantPermissions": true,
"appium:noReset": false,
"appium:newCommandTimeout": 120
}

Merged on top of platform defaults.

Vendor-specific options

For BrowserStack/Sauce Labs, the platform builds bstack:options / sauce:options automatically from credentials + cloud_config. You can override individual keys via:

{
"bstackOptions": {
"debug": true,
"networkLogs": false,
"buildName": "release-v3.2"
}
}

These get nested under bstack:options in the final capability dict.

Common patterns

Login flow

steps:
- action: type
selector: accessibility:username-field
value: "{{username}}"
- action: type
selector: accessibility:password-field
value: "{{password}}"
- action: tap
selector: accessibility:login-button
- action: wait_for
selector: accessibility:home-screen
timeout: 15000

Scroll-and-find

steps:
- action: scroll_to
selector: accessibility:settings-link
- action: tap
selector: accessibility:settings-link

Form input with validation

steps:
- action: clear
selector: accessibility:email-field
- action: type
selector: accessibility:email-field
value: "invalid"
- action: tap
selector: accessibility:submit-button
- action: assert_visible
selector: accessibility:email-error
- action: assert_text
selector: accessibility:email-error
expectedText: "valid email"

What's different from UI testing

UI testsMobile tests
EnginePlaywright / Selenium / HtmlUnitAppium (UiAutomator2 / XCUITest)
Selector syntaxCSS / XPathaccessibility: / id: / xpath: (Appium-style)
home / back actionsN/ANative nav
swiperarecommon
App contextURL-basedPackage or pre-installed

Element discovery

Use Inspect Elements on the mobile app's detail page to crawl screens and capture available accessibility IDs. Saves accidental selector drift when the app's resource IDs change.

Tips

  1. Lean on accessibility IDs — they survive UI redesigns.
  2. Use wait_for aggressively — mobile UIs animate, and tap on an off-screen element fails. wait_for makes tests stable.
  3. Keep tests short — < 20 steps per test. Long tests are harder to debug.
  4. Tag step results with screenshots — adds action: screenshot after critical state transitions. Auto-attached to the run result for triage.
  • Local emulator — set up Appium locally to develop tests
  • Device farms — run the same YAML on real BrowserStack devices
  • Credentials{{username}} / {{password}} come from the vault