In Appium, what do appium:usePreinstalledWDA and appium:webDriverAgentUrl change about an iOS session?
answer
- both skip part of session start
- one skips the build only
- the other skips launching too
- you inherit the agent's lifecycle
- version skew becomes your problem
basics
~10 sBoth skip part of the WebDriverAgent sequence. appium:usePreinstalledWDA reuses an agent already installed on the target instead of compiling one; appium:webDriverAgentUrl points the driver at an agent already running, skipping build, install and launch.
solid answer
~40 sBy default Appium's XCUITest driver builds WebDriverAgent with `xcodebuild`, signs it, installs it and launches it before your first command. `appium:usePreinstalledWDA` removes the build: the driver assumes a runner is already installed on the simulator or device and starts that one. `appium:webDriverAgentUrl` removes more — it names a URL where an agent is already running, so the driver skips build, install and launch entirely and simply talks to it. Both buy session-start time and hand you an artifact to own: the installed runner must stay signed and current with the driver, and a long-lived agent is shared state whose lifetime and cleanliness are now yours.
code
json · 12 lines{
"capabilities": {
"alwaysMatch": {
"platformName": "iOS",
"appium:automationName": "XCUITest",
"appium:bundleId": "com.example.housekeeping",
"appium:usePreinstalledWDA": true,
"appium:wdaLocalPort": 8101
},
"firstMatch": [{}]
}
}go deeper
Recall that Appium's XCUITest driver builds WebDriverAgent by default, and that these two capabilities are the ways to reuse an existing agent instead of compiling one each time.
Explain exactly which steps each capability removes — build only, versus build, install and launch — and name the ports involved, appium:wdaLocalPort in particular, once the driver stops choosing them for you.
Demonstrate that you plan the upkeep: who reinstalls the agent after a driver upgrade, how signing is renewed across a fleet, and how a run detects that the agent answering is the one intended.
Own the trade at lane level: skipping the build converts a slow, self-healing step into a fast one that fails silently, so pinning is only defensible where an owner, an automated rebuild and a verification step already exist.
## Two opt-outs that skip different amounts of work By default Appium's XCUITest driver builds WebDriverAgent with `xcodebuild`, signs it, installs it on the target and launches it before the first command of a session. `appium:usePreinstalledWDA` and `appium:webDriverAgentUrl` each remove part of that sequence, but they cut it at different points — and where the cut falls decides who owns the agent's lifecycle. ## `appium:usePreinstalledWDA` — skip the build, keep the start-up With this capability set, the driver stops compiling. It assumes a WebDriverAgent runner is already installed on the simulator or device and starts that one instead. You get back the build time, which is the expensive part, while the driver still launches the agent and waits for its HTTP server to answer. What you now own: - **Getting the agent onto every target** in the first place, and onto new devices as the fleet changes. - **Keeping it signed.** On a real iPhone the installed runner must remain one the device will launch. - **Keeping it current.** An agent built against an older driver is version skew, and skew shows up as odd command behaviour rather than a clean error. ## `appium:webDriverAgentUrl` — skip build, install and launch This one goes further. It names a URL where a WebDriverAgent is already running, and the driver simply talks to it: no build, no install, no launch, no readiness polling of its own. It is also the escape hatch for hosts where the default `xcodebuild` startup strategy is not available at all. What you now own: - **The agent process** — starting it, keeping it alive, restarting it when it dies mid-run. - **Cleanliness between sessions.** A long-lived agent is shared state, and whatever one session leaves behind travels to the next. - **The address.** Nothing negotiates the URL for you, so it must be right per host and per target. ## The ports around it `appium:wdaLocalPort` is the host-side port the driver uses to reach the agent, `appium:wdaRemotePort` is the port on the target, and `appium:wdaBindingIP` controls the address the agent binds to. These matter more once you stop letting the driver do everything: when the driver launches its own agent it can be handed a free port per session, whereas an agent you started yourself sits on the port you gave it, and two sessions aimed at the same one collide. ## Side by side | | `appium:usePreinstalledWDA` | `appium:webDriverAgentUrl` | |---|---|---| | build with `xcodebuild` | skipped | skipped | | install on the target | assumed already done | assumed already done | | launch the agent | the driver still does it | you already did it | | agent lifetime | per session | as long as you keep it up | | what you supply | an installed, signed runner | a running agent and its URL | ## When each one is honest - Reach for `appium:usePreinstalledWDA` when session-start time is the problem and you can keep a current, signed agent installed on every target — a device lab with a provisioning step is its natural home. - Reach for `appium:webDriverAgentUrl` when something else already owns the agent: a host that cannot run the default build strategy, or a setup where one agent deliberately serves a series of sessions. - Stay on the default build when hosts are disposable, the fleet churns, or nobody has agreed to own an artifact. The build is slow, but it is self-healing and always produces an agent that matches the driver in play. ## The failure mode to expect Both capabilities move a class of problem from session start into the middle of a run. A hotel housekeeping-status suite that would have failed loudly while building an agent instead starts cleanly and then behaves oddly: a find that returns nothing on the room list, a gesture that lands in the wrong place, an occasional session that never becomes usable. The cause is that the agent answering is not the agent the driver expects. So when you take the build out of the session, put something else in its place: 1. A provisioning step that rebuilds, re-signs and reinstalls the agent whenever the XCUITest driver is upgraded. 2. A start-of-run check that the agent answering is the one you meant to pin. 3. A rule for teardown — decide explicitly whether a long-lived agent survives a run, and what resets it if it should not. That is the trade in one line: you exchange a slow, self-correcting step for a fast one whose failure is quiet, and quiet failures need somebody watching for them.
- If you set appium:webDriverAgentUrl, what stops working that the driver used to handle?The driver no longer builds, installs, launches or waits on the agent, so nothing repairs a dead or stale one for you. You also lose per-session port assignment: the agent sits at the address you gave it, so isolating concurrent sessions becomes your job rather than the driver's.
- How would you detect that a pinned agent has drifted out of step with the driver?Make it explicit rather than inferred: rebuild and reinstall the agent in the same change that upgrades the XCUITest driver, and add a start-of-run check that the agent answering matches what the lane expects. Skew otherwise shows up as intermittent command failures, not a clear error.
saying these in an interview costs you the question
- Treating the two capabilities as interchangeable ways to say reuse the agent
- Assuming appium:usePreinstalledWDA also skips launching the agent
- Thinking a pinned agent needs no rebuild after a driver upgrade
- Ignoring that a long-lived agent is shared state between sessions
- Believing skipping the build removes the signing requirement on real devices