- Speed and determinism when selectors are stable: native Appium runs with no AI round-trip.
- Resilience when the UI shifts, a popup appears, or a selector breaks: the step heals itself by falling back to AI instead of failing the test.
The appiumHandler parameter
aiExecute accepts an optional appiumHandler: a function that receives the live driver and runs your native Appium / WebdriverIO code.
How it runs
When you pass anappiumHandler, each call to aiExecute does the following:
- Runs the handler first against the live driver. Fast, deterministic, no AI call.
- Logs the step to the GPT Driver dashboard (a screenshot plus the handler’s source) so the native step is visible alongside your AI steps for debugging.
- On success, returns immediately. The AI is never called.
-
On failure (the handler throws), the SDK logs a warning and runs the natural-language instruction with AI to recover:
That message is greppable in your run logs, so you can see exactly which steps fell back to AI.
The
appiumHandler and the instruction should express the same intent. The handler is the fast path; the instruction is the recovery path that must achieve the same result when the handler can’t.A reusable step helper
In practice you wrap the pattern in a small helper so every step reads as “native code, with an AI description to fall back to”:Worked example
A full flow built this way. Native Appium drives every step; AI only engages when a native block throws (a moved selector, a slow load, an unexpected popup):test/specs/saved-lines.spec.js
Falling back to AI for reads, too
The same try-native-first idea works for data you read off the screen. Try a native selector, and fall back toextract (or assert) when the native read fails:
When to reach for AI directly
Skip the handler and callaiExecute(prompt) with no native code when:
- The target is a WebView, canvas, map, or other non-native element that selectors can’t reach reliably. See non-native elements.
- The step is inherently visual or fuzzy (“dismiss whatever popup is on screen”, “tap the cheapest room option”).
- You are prototyping and don’t have stable selectors yet. Add
appiumHandlerblocks later to speed up the steps that run often.
Tips
- Keep handlers fast and let them throw early. Use short
waitFor*timeouts inside handlers so a missing element falls back to AI quickly instead of burning the full default timeout. - Pair the handler and the prompt. They should do the same thing; the prompt is what runs when the handler can’t.
- Combine with caching. Set
cachingModeso the AI fallback steps that do run also get cached. See the reference. - Review fallbacks on the dashboard. Every native step is logged with a screenshot, and every fallback emits the greppable warning above, so you can see where the suite is leaning on AI and tighten those selectors.

