WebDriverAgent can hand a second app crash detection now; phoneshell's open_app never asks for it
WDA 16.15.0 added a flag so a later launch can claim the session's "application under test" status, with its quiescence inheritance, alert monitoring and crash detection. phoneshell already duplicates the first two itself. It has nothing for the third, and never sets the flag.
WebDriverAgent 16.15.0, released 12 October 2026, added an opt-in flag, asAppUnderTest, so a later /wda/apps/launch call can make its app the one WDA tracks as the application under test. phoneshell's two session-creation call sites never pass a bundle id on purpose, and its three-attempt open_app never passes the new flag either. The app WDA considers "under test" during a phoneshell run is not the app the agent is looking at. It is whatever was in front the last time a stale session got rebuilt.
What WDA 16.15.0 changed, and on which date
PR #1289, merged 12 October 2026 as commit f5c0688, adds asAppUnderTest to the /wda/apps/launch route. Before this release, a session's application under test could only be set once, at session creation, by passing a bundleId capability. Every later /wda/apps/launch call started a new app without ever replacing that designation. The PR description states the three things being application-under-test buys an app: later launches inherit its quiescence setting, system alerts over it are respected, and its unexpected termination is reported as a crash (an FBApplicationCrashedException) rather than read as an ordinary state change. The flag defaults to false, so WDA's own authors describe existing behaviour as unchanged unless a caller opts in.
phoneshell's create_session (wda/client.py:248) resolves its bundle id as bundle_id or self.default_bundle_id, and both call sites (lines 208 and 234) pass neither. default_bundle_id starts at None. It only ever gets set inside the stale-session recovery branch (lines 190-197), whose own comment explains why it does not simply press home and re-attach: "a session created with no bundleId makes WDA switch the app under test, which sends the phone to the home screen and closes whatever was just opened." So the mechanism that occasionally gives phoneshell a tracked application under test is a side-effect workaround for a different WDA behaviour, not a deliberate choice, and it carries over whatever was in front at the moment of recovery, which can be stale by the time the agent has moved three apps further into a task.
Three things the flag buys, checked against phoneshell's own code
| Protection tied to "application under test" | What WDA does with it | phoneshell's own mechanism | Gap | Source |
|---|---|---|---|---|
| Quiescence inheritance | A later launch with no explicit setting copies the tracked app's wait-for-idle policy | Every phoneshell launch call sends shouldWaitForQuiescence explicitly (actions.py fallback loop, wda/client.py:380); inheritance is never consulted | None: already overridden on every call | wda/client.py launch_app |
| System alert monitoring | WDA's FBAlertsMonitor watches for alerts over the tracked app specifically | Alerts are read from the accessibility tree snapshot on every step regardless of which app is foreground (actions.py:179-187) | None: already app-agnostic | actions.py snapshot |
| Crash detection | Unexpected termination of the tracked app raises FBApplicationCrashedException, distinct from a normal state change | app_state() returns the same code, 1 ("not running"), for a crash, a clean quit, or an app never launched (wda/client.py app_state; actions.py:891) | Real: nothing in phoneshell distinguishes a crash from a quiet exit | actions.py:891-894 |
The first two rows are not gaps. phoneshell was built around the assumption, stated directly in open_app's own docstring, that "WebDriverAgent returns success for activate and launch whether or not the app actually comes forward," so it never trusted WDA's bookkeeping for either of those two things to begin with: it polls active_app_info() itself with a 4-second, 0.4-second-interval wait, and it reads alerts out of whatever snapshot it already took. The third row is different. There is no code path, anywhere in actions.py or wda/client.py, that asks whether a now-missing app crashed versus was cleanly terminated versus was never running at all. Those three situations produce the identical string: "not running."
What it means if you run a WDA-backed phone agent
- Do not assume "application under test" tracks your agent's actual focus unless you deliberately set it. phoneshell's history shows a session with no claimed app is a reasonable default: it sidesteps a documented WDA behaviour (home-screen bounce on re-attach) that cost more than the bookkeeping was worth.
- If you want WDA's crash signal, you now have a cheap way to get it without the create-session tradeoff: pass
asAppUnderTest: trueon the specific/wda/apps/launchcall for the app you actually want watched, mid-session, without touching how the session itself was created. - If your own harness already polls foreground state and reads alerts itself, as phoneshell does, two of the flag's three benefits are redundant. Check the third before assuming you are covered: can your code currently tell a crash apart from a clean exit? phoneshell's answer today is no.
Check it yourself
- The commit:
https://github.com/appium/WebDriverAgent/commit/f5c068873ff6dcd1ce444d26246c102cc379d5bf, PR #1289, merged into 16.15.0. - phoneshell never sends the flag:
grep -rn asAppUnderTest phoneshell/returns nothing. - Neither session call names a bundle:
grep -n "create_session()" phoneshell/wda/client.pyshows both call sites with no argument. - The workaround comment:
sed -n '188,206p' phoneshell/wda/client.py. - The crash/quit/never-ran conflation:
sed -n '885,895p' phoneshell/actions.py; the state map has no fifth value for "crashed." - The multi-app task count:
grep -L "^app: com.apple" environments/*.yaml | wc -lplus manual check of which files reference a second bundle id, listed above.
What would prove this wrong
The claim is that phoneshell cannot currently tell a crashed app from a cleanly closed one. Test: launch any installed app with asAppUnderTest: true directly against a phoneshell-managed WDA instance, force-kill it from Springboard, and read /wda/activeAppInfo. If phoneshell's existing code path surfaces a distinct error for that case today, this is wrong. We expect it to report the same "not running" string app_state() already returns for every other kind of absence. We will publish the result, or say we did not run it, by 15 November 2026.
Sources
- WebDriverAgent, commit f5c0688, "feat: add asAppUnderTest flag to /wda/apps/launch" (PR #1289), merged into v16.15.0, 12 October 2026
- WebDriverAgent CHANGELOG.md, v16.15.0 through v16.13.0 (read 14 October 2026)
- phoneshell source: actions.py (open_app, app_state usage), wda/client.py (create_session, launch_app, stale-session recovery), environments/*.yaml (read 14 October 2026)