Skip to content

Commit b79dd0f

Browse files
committed
Release v1.1.0: WebView CDP, evalWebViewScript, swipe fixes
1 parent 2d9c2e6 commit b79dd0f

3 files changed

Lines changed: 208 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,85 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [1.1.0] - 2026-03-25
11+
12+
### Added
13+
- **WebView CDP support for Android** — the DeviceLab driver now connects to WebViews via Chrome DevTools Protocol for element finding and JavaScript execution, instead of relying solely on the native UiAutomator accessibility tree
14+
```bash
15+
# Automatic — when a WebView is detected, CDP is used transparently
16+
maestro-runner --driver devicelab test webview-flow.yaml
17+
```
18+
- **Chrome browser CDP on Android** — the DeviceLab driver can now automate Chrome browser on Android devices via CDP, enabling web testing on real Android devices
19+
- **`evalWebViewScript` command** — execute inline JavaScript in a mobile WebView via CDP. Returns the result as a string, optionally stored in an output variable
20+
```yaml
21+
# Inline script
22+
- evalWebViewScript: "return document.title"
23+
24+
# With output variable
25+
- evalWebViewScript:
26+
script: "return document.querySelector('#price').textContent"
27+
output: price
28+
29+
# Use the result
30+
- assertTrue: ${price == '$7.50'}
31+
```
32+
- **`runWebViewScript` command** — load and execute a JavaScript file in a mobile WebView via CDP. Supports environment variables injected as `window.__env`
33+
```yaml
34+
# Simple file execution
35+
- runWebViewScript: scripts/extract-data.js
36+
37+
# With environment variables and output
38+
- runWebViewScript:
39+
file: scripts/validate-cart.js
40+
env:
41+
EXPECTED_TOTAL: "29.99"
42+
output: validationResult
43+
```
44+
- **Network idle detection and DOM stability waits** — after navigations (in both browser and WebView contexts), maestro-runner now waits for network idle and DOM stability before proceeding, reducing flakiness on pages with async loading
45+
- **CDP RAF-based visibility polling** — browser commands now use `requestAnimationFrame`-based polling for element visibility, improving reliability for dynamically rendered content
46+
- **CDP `<select>` option support** — `tapOn` with option elements now correctly selects the option via JavaScript instead of attempting a click
47+
- **CDP JS click fallback** — when a native click fails on a browser element, falls back to JavaScript `.click()` for better reliability with overlapping elements
48+
49+
### Changed
50+
- Default WDA swipe duration changed from 300ms to 100ms for faster, more responsive swipe gestures on iOS
51+
- JavaScript helper code extracted from Go string literals into dedicated embedded `.js` files for easier maintenance ([#37](https://github.com/devicelab-dev/maestro-runner/pull/37))
52+
53+
### Fixed
54+
- **Swipe coordinates now match Maestro behavior** across all drivers (UIAutomator2, DeviceLab, WDA, Appium) — previously, swipe start/end positions differed from Maestro's implementation
55+
- **`assertNotVisible` now 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
56+
- **Filter out-of-bounds elements from page source searches** — elements with coordinates outside the visible screen bounds are now excluded from search results, preventing false matches on off-screen elements ([#39](https://github.com/devicelab-dev/maestro-runner/issues/39))
57+
- **Text node attribute error** — fixed `TypeError: this.getAttribute is not a function` when browser CDP encounters text nodes that don't have HTML attributes ([#35](https://github.com/devicelab-dev/maestro-runner/issues/35), [#36](https://github.com/devicelab-dev/maestro-runner/pull/36))
58+
- **iOS WDA session lifecycle** — improved driver reliability with better session creation, cleanup, and error recovery
59+
- **`--team-id` no longer required for auto-detected simulators** — when a booted simulator is auto-detected, `--team-id` is automatically skipped since simulators don't need code signing
60+
```bash
61+
# Before: required --team-id even when simulator is already booted
62+
# Now: just works
63+
maestro-runner --platform ios test flow.yaml
64+
```
65+
- **Flutter reconnection** — skip retries for non-Flutter apps instead of wasting time on connection attempts. Non-Flutter apps now pay zero retry cost
66+
- **WebView CDP forwarder** — wired `SetWebViewForwarder` in the DeviceLab driver, which was never connected — elements were previously found only via native UiAutomator accessibility tree even when a WebView was present
67+
- **hideKeyboard reliability** — on-device agent now uses `KEYCODE_ESCAPE` first (keyboard-only, no navigation side-effects), falls back to `KEYCODE_BACK` if needed. Retries up to 3 times with keyboard visibility polling
68+
- **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
69+
- **CDP text match filtering** — text-based visibility checks (`text`, `textContains`, `textRegex`) now filter to the deepest matching element, preventing false positives from ancestor elements whose `textContent` includes hidden children's text
70+
71+
### Contributors
72+
73+
[@tmahesh](https://github.com/tmahesh)
74+
1. Fixed text node attribute error in browser CDP ([#36](https://github.com/devicelab-dev/maestro-runner/pull/36))
75+
2. Refactored JS helper code into embedded files ([#37](https://github.com/devicelab-dev/maestro-runner/pull/37))
76+
77+
[@mahesh-e27](https://github.com/mahesh-e27)
78+
1. Reported text node attribute bug in browser CDP ([#35](https://github.com/devicelab-dev/maestro-runner/issues/35))
79+
80+
[@sircharleswatson](https://github.com/sircharleswatson)
81+
1. Reported `assertVisible` passing for off-screen text in browser ([#39](https://github.com/devicelab-dev/maestro-runner/issues/39))
82+
83+
[@satishs22](https://github.com/satishs22)
84+
1. Reported `tapOn` timeout issue on Android emulator ([#25](https://github.com/devicelab-dev/maestro-runner/issues/25))
85+
86+
[@chrisjin-swipe](https://github.com/chrisjin-swipe)
87+
1. Reported `inputText` character skipping on Android ([#32](https://github.com/devicelab-dev/maestro-runner/issues/32))
88+
1089
## [1.0.9] - 2026-03-11
1190

1291
### Added

docs/releases/v1.1.0.md

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
## What's New
2+
3+
### WebView CDP Support for Android
4+
5+
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.
6+
7+
```bash
8+
# Automatic — CDP kicks in when a WebView is visible
9+
maestro-runner --driver devicelab test webview-flow.yaml
10+
```
11+
12+
```yaml
13+
# Your flow doesn't change — WebView elements are found via CDP transparently
14+
- launchApp:
15+
appId: com.example.app
16+
clearState: true
17+
- tapOn: "Open WebView"
18+
- assertVisible: "Welcome" # Found via CDP inside the WebView
19+
- tapOn:
20+
id: "submit-button" # CDP element finding
21+
```
22+
23+
### Chrome Browser CDP on Android
24+
25+
The DeviceLab driver can now automate Chrome browser on real Android devices via CDP, enabling web testing directly on Android hardware.
26+
27+
### New Commands: `evalWebViewScript` & `runWebViewScript`
28+
29+
Execute JavaScript inside a mobile WebView via CDP — the WebView equivalents of `evalBrowserScript` and `runBrowserScript`.
30+
31+
**`evalWebViewScript`** — inline JavaScript execution:
32+
33+
```yaml
34+
# Simple — returns document title
35+
- evalWebViewScript: "return document.title"
36+
37+
# With output variable
38+
- evalWebViewScript:
39+
script: "return document.querySelector('#price').textContent"
40+
output: price
41+
42+
# Use the result in assertions
43+
- assertTrue: ${price == '$7.50'}
44+
```
45+
46+
**`runWebViewScript`** — execute a JavaScript file:
47+
48+
```yaml
49+
# Simple file execution
50+
- runWebViewScript: scripts/extract-data.js
51+
52+
# With environment variables and output
53+
- runWebViewScript:
54+
file: scripts/validate-cart.js
55+
env:
56+
EXPECTED_TOTAL: "29.99"
57+
output: validationResult
58+
```
59+
60+
### Network Idle Detection & DOM Stability Waits
61+
62+
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.
63+
64+
### CDP Browser Improvements
65+
66+
- **RAF-based visibility polling** — element visibility checks now use `requestAnimationFrame`-based polling, improving reliability for dynamically rendered content
67+
- **`<select>` option support** — `tapOn` with `<option>` elements correctly selects the option via JavaScript instead of attempting a click
68+
- **JS click fallback** — when a native click fails on a browser element, falls back to JavaScript `.click()` for better reliability with overlapping elements
69+
70+
## Changes
71+
72+
- Default WDA swipe duration changed from 300ms to **100ms** for faster, more responsive swipe gestures on iOS
73+
- JavaScript helper code extracted from Go string literals into dedicated embedded `.js` files for easier maintenance ([#37](https://github.com/devicelab-dev/maestro-runner/pull/37))
74+
75+
## Bug Fixes
76+
77+
- **Swipe coordinates now match Maestro behavior** across all drivers (UIAutomator2, DeviceLab, WDA, Appium) — previously, swipe start/end positions differed from Maestro's implementation
78+
- **`assertNotVisible` now 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
79+
- **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](https://github.com/devicelab-dev/maestro-runner/issues/39))
80+
- **Text node attribute error** — fixed `TypeError: this.getAttribute is not a function` when browser CDP encounters text nodes ([#35](https://github.com/devicelab-dev/maestro-runner/issues/35), [#36](https://github.com/devicelab-dev/maestro-runner/pull/36))
81+
- **iOS WDA session lifecycle** — improved driver reliability with better session creation, cleanup, and error recovery
82+
- **`--team-id` no longer required for auto-detected simulators** — when a booted simulator is auto-detected, `--team-id` is automatically skipped
83+
```bash
84+
# Before: required --team-id even when simulator is already booted
85+
# Now: just works
86+
maestro-runner --platform ios test flow.yaml
87+
```
88+
- **Flutter reconnection** — skip retries for non-Flutter apps instead of wasting time on connection attempts. Non-Flutter apps now pay zero retry cost
89+
- **WebView CDP forwarder** — wired `SetWebViewForwarder` in the DeviceLab driver, which was never connected — elements were previously found only via native UiAutomator accessibility tree
90+
- **hideKeyboard reliability** — on-device agent now uses `KEYCODE_ESCAPE` first (keyboard-only, no navigation side-effects), falls back to `KEYCODE_BACK` if needed. Retries up to 3 times with keyboard visibility polling
91+
- **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
92+
- **CDP text match filtering** — text-based visibility checks (`text`, `textContains`, `textRegex`) now filter to the deepest matching element, preventing false positives from ancestor elements whose `textContent` includes hidden children's text
93+
94+
## Thanks
95+
96+
Thanks to everyone who reported issues and contributed code!
97+
98+
- **[@tmahesh](https://github.com/tmahesh)** — fixed text node attribute error in browser CDP ([#36](https://github.com/devicelab-dev/maestro-runner/pull/36)), refactored JS helpers into embedded files ([#37](https://github.com/devicelab-dev/maestro-runner/pull/37))
99+
- **[@mahesh-e27](https://github.com/mahesh-e27)** — reported text node attribute bug in browser CDP ([#35](https://github.com/devicelab-dev/maestro-runner/issues/35))
100+
- **[@sircharleswatson](https://github.com/sircharleswatson)** — reported `assertVisible` passing for off-screen text in browser ([#39](https://github.com/devicelab-dev/maestro-runner/issues/39))
101+
- **[@satishs22](https://github.com/satishs22)** — reported `tapOn` timeout issue on Android emulator ([#25](https://github.com/devicelab-dev/maestro-runner/issues/25))
102+
- **[@chrisjin-swipe](https://github.com/chrisjin-swipe)** — reported `inputText` character skipping on Android ([#32](https://github.com/devicelab-dev/maestro-runner/issues/32))
103+
104+
## Installation
105+
106+
```bash
107+
curl -fsSL https://open.devicelab.dev/install/maestro-runner | bash
108+
109+
# Install this specific version
110+
curl -fsSL https://open.devicelab.dev/install/maestro-runner | bash -s -- --version 1.1.0
111+
```
112+
113+
## Documentation
114+
115+
- [Getting Started](https://open.devicelab.dev/maestro-runner/docs/getting-started)
116+
- [Flow Commands](https://open.devicelab.dev/maestro-runner/docs/flow-commands)
117+
- [CLI Reference](https://open.devicelab.dev/maestro-runner/docs/cli-reference)
118+
- [Technical Approach](https://open.devicelab.dev/maestro-runner/docs/technical-approach)
119+
- [Web Testing Guide](https://open.devicelab.dev/maestro-runner/docs/web-testing)
120+
121+
## Platform Support
122+
- macOS Intel (amd64) — Signed & Notarized
123+
- macOS Apple Silicon (arm64) — Signed & Notarized
124+
- Linux amd64
125+
- Linux arm64
126+
127+
---
128+
Built by [DeviceLab.dev](https://devicelab.dev)

pkg/cli/cli.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import (
1111

1212
// Build info — set at build time via -ldflags.
1313
var (
14-
Version = "1.0.9"
14+
Version = "1.1.0"
1515
Commit = "unknown"
1616
BuildDate = "unknown"
1717
)

0 commit comments

Comments
 (0)