|
| 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) |
0 commit comments