v1.1.0
What's New
WebView CDP Support for Android
The DeviceLab driver now connects to Android WebViews via Chrome DevTools Protocol. When a WebView is detected, maestro-runner automatically uses CDP for element finding and JavaScript execution — no configuration needed.
# Automatic — CDP kicks in when a WebView is visible
maestro-runner --driver devicelab test webview-flow.yaml# Your flow doesn't change — WebView elements are found via CDP transparently
- launchApp:
appId: com.example.app
clearState: true
- tapOn: "Open WebView"
- assertVisible: "Welcome" # Found via CDP inside the WebView
- tapOn:
id: "submit-button" # CDP element findingChrome Browser CDP on Android
The DeviceLab driver can now automate Chrome browser on real Android devices via CDP, enabling web testing directly on Android hardware.
New Commands: evalWebViewScript & runWebViewScript
Execute JavaScript inside a mobile WebView via CDP — the WebView equivalents of evalBrowserScript and runBrowserScript.
evalWebViewScript — inline JavaScript execution:
# Simple — returns document title
- evalWebViewScript: "return document.title"
# With output variable
- evalWebViewScript:
script: "return document.querySelector('#price').textContent"
output: price
# Use the result in assertions
- assertTrue: ${price == '$7.50'}runWebViewScript — execute a JavaScript file:
# Simple file execution
- runWebViewScript: scripts/extract-data.js
# With environment variables and output
- runWebViewScript:
file: scripts/validate-cart.js
env:
EXPECTED_TOTAL: "29.99"
output: validationResultNetwork Idle Detection & DOM Stability Waits
After navigations (in both browser and WebView contexts), maestro-runner now waits for network idle and DOM stability before proceeding. This reduces flakiness on pages with async loading — no more waitForAnimationToEnd hacks after navigation.
CDP Browser Improvements
- RAF-based visibility polling — element visibility checks now use
requestAnimationFrame-based polling, improving reliability for dynamically rendered content <select>option support —tapOnwith<option>elements correctly selects the option via JavaScript instead of attempting a click- JS click fallback — when a native click fails on a browser element, falls back to JavaScript
.click()for better reliability with overlapping elements
Changes
- Default WDA swipe duration changed from 300ms to 100ms for faster, more responsive swipe gestures on iOS
- JavaScript helper code extracted from Go string literals into dedicated embedded
.jsfiles for easier maintenance (#37)
Bug Fixes
- Swipe coordinates now match Maestro behavior across all drivers (UIAutomator2, DeviceLab, WDA, Appium) — previously, swipe start/end positions differed from Maestro's implementation
assertNotVisiblenow correctly polls for disappearance instead of polling for appearance — previously, the command would pass immediately if the element wasn't visible, without waiting for it to disappear after an action- Filter out-of-bounds elements from page source searches — elements with coordinates outside the visible screen bounds are now excluded, preventing false matches on off-screen elements (#39)
- Text node attribute error — fixed
TypeError: this.getAttribute is not a functionwhen browser CDP encounters text nodes (#35, #36) - iOS WDA session lifecycle — improved driver reliability with better session creation, cleanup, and error recovery
--team-idno longer required for auto-detected simulators — when a booted simulator is auto-detected,--team-idis automatically skipped# Before: required --team-id even when simulator is already booted # Now: just works maestro-runner --platform ios test flow.yaml
- Flutter reconnection — skip retries for non-Flutter apps instead of wasting time on connection attempts. Non-Flutter apps now pay zero retry cost
- WebView CDP forwarder — wired
SetWebViewForwarderin the DeviceLab driver, which was never connected — elements were previously found only via native UiAutomator accessibility tree - hideKeyboard reliability — on-device agent now uses
KEYCODE_ESCAPEfirst (keyboard-only, no navigation side-effects), falls back toKEYCODE_BACKif needed. Retries up to 3 times with keyboard visibility polling - In-WebView navigation — when visibility check fails during in-WebView page navigation (JS context destroyed), refreshes page reference and retries instead of skipping CDP entirely
- CDP text match filtering — text-based visibility checks (
text,textContains,textRegex) now filter to the deepest matching element, preventing false positives from ancestor elements whosetextContentincludes hidden children's text
Thanks
Thanks to everyone who reported issues and contributed code!
- @tmahesh — fixed text node attribute error in browser CDP (#36), refactored JS helpers into embedded files (#37)
- @mahesh-e27 — reported text node attribute bug in browser CDP (#35)
- @sircharleswatson — reported
assertVisiblepassing for off-screen text in browser (#39) - @satishs22 — reported
tapOntimeout issue on Android emulator (#25) - @chrisjin-swipe — reported
inputTextcharacter skipping on Android (#32)
Installation
curl -fsSL https://open.devicelab.dev/install/maestro-runner | bash
# Install this specific version
curl -fsSL https://open.devicelab.dev/install/maestro-runner | bash -s -- --version 1.1.0Documentation
Platform Support
- macOS Intel (amd64) — Signed & Notarized
- macOS Apple Silicon (arm64) — Signed & Notarized
- Linux amd64
- Linux arm64
Built by DeviceLab.dev