In Appium, what does driver proxy mode change about which tier answers a command?
answer
- The driver may not be the answerer
- Forwarded to the device-side server
- Proxy-avoid list is the exception list
- A JS array is a declaration
basics
~20 sIn proxy mode the driver forwards the request to its device-side agent, which answers it; only routes on the driver's proxy-avoid list run in the driver's own code. So driver source can understate what a session accepts.
solid answer
~40 sA driver that automates through a server running on the device usually proxies: `BaseDriver` forwards each request to that agent unless the route matches the driver's proxy-avoid list (`jwpProxyAvoid`, an array of regular expressions). That inverts how you read driver source — a JavaScript array describes what the driver *would* answer, and for a proxied route the request never reaches it. Appium's Espresso driver on Android is the measured case: its Node-side driver declares `id`, `class name` and `accessibility id`, but it forces proxying on and its proxy-avoid list does not cover the find routes, so the on-device Espresso server answers a find and its own `Strategy.kt` enum — which includes `xpath`, `-android datamatcher`, `-android viewmatcher` and `-android viewtag` — is the effective list.
go deeper
Know that a command you send does not always run inside the Appium driver's own code; many are forwarded to a server running on the device and answered there.
Explain the proxy-avoid list: routes it matches are handled in the driver, and everything else is forwarded to the device-side agent that actually implements it.
Demonstrate the habit of checking whether a route is proxied before trusting a driver's source, and of reading the agent's own evidence rather than only the server log.
Own the risk this creates across a fleet: behaviour that lives on the device changes with the deployed agent, not with the driver release, so pin and verify both halves.
## What proxy mode means inside an Appium driver The Appium drivers that automate a native app usually do it through a second HTTP server that runs on the device or the target itself. When that is the shape, the driver has a choice for every incoming request: implement it in its own Node code, or forward it to that agent and hand back whatever comes out. Forwarding is proxying, and for drivers built this way it is the default path rather than an optimisation. `BaseDriver` supplies the machinery. A driver declares that it proxies, points the proxy at the agent's address, and declares the routes it will *not* proxy — the proxy-avoid list, spelled `jwpProxyAvoid` in driver source and written as an array of regular expressions. Everything matching that list stays inside the driver. Everything else leaves the process. ## The proxy-avoid list is the real contract This inverts the natural way to read a driver's source: - If a route is on the proxy-avoid list, the driver's own implementation is the behaviour. - If it is not, the device-side server's implementation is the behaviour, and the driver's arrays say nothing about it. - A route missing from the proxy-avoid list is therefore a route the agent owns. - The two halves can disagree without either being a bug: they describe different tiers. ## The measured case — Appium's Espresso driver on Android Android's Espresso driver is the clearest example. Its Node-side driver file declares three locator strategies: `id`, `class name` and `accessibility id`. The same file forces proxying on, and its proxy-avoid list does not cover the find routes, so a find is answered by the Espresso server running on the device. That server's own `Strategy.kt` enum is the effective list, and it is much longer — `class name`, `css selector`, `id`, `name`, `link text`, `partial link text`, `xpath`, `accessibility id`, `text`, `-android viewtag`, `-android datamatcher` and `-android viewmatcher`. Reading the Node array and concluding that this driver has no XPath strategy is a documented way to be confidently wrong. The same driver shows the other direction too: its on-device server still registers touch-action routes the Appium 3 server no longer declares, and the driver still carries `/touch/perform` in its proxy-avoid regexes. The lower tier keeps its own history, on its own release schedule. ## Which drivers have something to proxy to Not every driver has a lower HTTP tier at all: - Android's UiAutomator2 driver proxies to `io.appium.uiautomator2.server` running on the device. - Apple's XCUITest driver proxies to `WebDriverAgent` running on the target. - Android's Espresso driver proxies to the Espresso server it installed as a test package. - The official Flutter driver has no HTTP agent to proxy to; it speaks the Dart VM Service Protocol over a WebSocket instead, so this whole question does not arise for it. ## Where this changes your debugging Suppose one gesture in one screen of a fuel-card expense suite fails. Which tier you accuse decides what you read next: | the route is | the code that ran | where the evidence is | |---|---|---| | on the proxy-avoid list | the driver's own method, in the server process | the Appium server's log for that session | | not on the list | the device-side agent's handler | the agent's own output, plus the forwarded status the driver recorded | A workable order of operations: 1. Establish whether the route is proxied before reading anything else. 2. If it is, treat the driver's source as a routing table, not as the implementation. 3. Check the agent against what the driver expects — it is deployed separately and can be older than the driver that installed it. 4. Only then reach for a capability change. ## What proxying does not change Session creation is never proxied: the driver creates the session, and only then can there be an agent to forward to. `mobile:` execute methods are dispatched by the driver's execute-method map, so they are driver-side by construction. And the client sees nothing of any of this — the response shape is identical whether the driver answered or merely relayed, which is precisely why the distinction has to be held in your head rather than read off the wire. ## The general rule When a fact about an Appium driver comes from a JavaScript array, ask whether that driver proxies the command before quoting the array as complete. The same caution applies to any NO_PROXY list you find. It is a small habit, and it removes a whole class of confident wrong answers — about which strategies work, about which commands exist, and about which tier you should be fixing.
- Appium's Espresso driver declares three locator strategies in its Node code — why is that not the effective list?Because that Android driver forces proxying on and its proxy-avoid list does not cover the find routes, so the Espresso server on the device answers a find. Its own `Strategy.kt` enum is the effective list and includes `xpath`, `-android datamatcher`, `-android viewmatcher` and `-android viewtag`. The Node array is a declaration, not a contract.
- How does proxy mode change where you look when a command fails?It moves the evidence one tier down. A proxied command is handled inside the device-side agent, so the Appium server may record little more than the forwarded request and its status. Read the agent's own output before blaming the driver, and check that the deployed agent matches what the driver expects of it.
Proxy mode is a switchboard with a short exception list: a handful of numbers are answered at the desk, and every other call is put straight through to the extension without the desk hearing a word of it.
saying these in an interview costs you the question
- Assumes the driver's Node code implements every command
- Reads a driver's declared array as the session's real list
- Thinks proxying is an optimisation rather than the default path
- Cannot say where a proxied command's evidence appears
- Believes the Appium server proxies straight to the device