Across an Appium device set with different Android System WebView builds, how do you keep web views drivable?
answer
- engine updates outside the OS release
- one pinned binary cannot fit all
- let the session choose per device
- offline runners cannot fetch anything
basics
~20 sAndroid System WebView updates independently of the OS, so one pinned Chromedriver cannot fit every phone. Ship a folder of builds, let each session pick per device, and keep the Apple half on debuggable builds and device settings instead.
solid answer
~40 sThe problem is that the engine rendering an Android web view updates on its own schedule, so two phones on the same OS release can need different Chromedriver builds. The durable setup is **a folder rather than a pin**: provision several binaries, point `appium:chromedriverExecutableDir` at them, and turn on `appium:enableWebviewDetailsCollection` so the session reads each web view's details and selects a compatible build. `appium:webviewDevtoolsPort` and `appium:ensureWebviewsHavePages` tidy up the detection itself. Autodownload via the `chromedriver_autodownload` insecure feature needs both server permission and network egress, which an isolated runner rarely has — hence the baked-in folder. `appium:chromedriverDisableBuildCheck` is not a fleet answer. The Apple half has no per-device binary at all: its variance is build debuggability and device settings.
go deeper
Know that Android System WebView updates on its own schedule, so two phones on the same OS release can need different Chromedriver builds even though nothing about the app changed.
Explain how a folder of binaries plus web-view details collection lets each session pick a compatible build, and what the local devtools port and the empty-web-view filter are doing.
Show how you keep an isolated runner working: pre-provisioned binaries, a deliberate refresh process, and failure signatures you can distinguish from ordinary waiting problems.
Own the supply of engine-matched binaries and, separately, the Apple-side build and device configuration, so that adding devices does not multiply per-device setup work for every engineer.
## Why one pinned binary is wrong for a set of devices On Android the engine that renders an app's embedded web view is usually **Android System WebView**, and it updates through the store independently of the OS release and of the browser. That means device uniformity is not something you can assert: two phones bought together, on the same Android version, drift apart as one takes an engine update and the other does not. Since Appium's Android drivers proxy web commands to **Chromedriver**, and each Chromedriver build supports only a narrow range of engine builds, a single pinned binary is a claim about the fleet that the platform will quietly falsify for you. The failure is partial, which is what makes it expensive. Most phones pass, one does not, and the run looks like flakiness rather than configuration. ## Making the session choose per device The setup that survives is a folder plus detection, rather than a pin: - `appium:chromedriverExecutableDir` points at a directory holding several Chromedriver builds, and the driver selects one compatible with the device it is on. - `appium:enableWebviewDetailsCollection` makes the driver read each web view's details, including the engine version, which is what turns that selection into an informed one. - `appium:webviewDevtoolsPort` sets the local port used while reaching the web view's debug socket, which matters when several sessions share a host. - `appium:ensureWebviewsHavePages` filters out web views reporting no pages, so a session does not settle on an empty one. - `appium:chromedriverExecutable` remains the right tool for the opposite case: one device, one binary, maximum reproducibility. ## Autodownload versus a baked-in folder The `chromedriver_autodownload` insecure feature — named to the server in its scoped form `uiautomator2:chromedriver_autodownload` — lets the driver fetch a matching build at session time. That is excellent on a developer machine and often unavailable where suites actually run: | | Autodownload | Provisioned folder | |---|---|---| | Needs server permission | yes, the insecure feature must be enabled | no | | Needs network egress from the host | yes | no | | Behaviour on a locked-down runner | fails at session time | unaffected | | Who keeps it current | the driver, per session | a deliberate refresh of the image | The trade is between convenience and determinism. A folder baked into the machine image never surprises a run and never depends on an outbound connection; the cost is that somebody has to add a build when a new engine version reaches the devices. ## What not to do `appium:chromedriverDisableBuildCheck` makes the mismatch stop complaining. It does not make the pair correct. Applied across a fleet it converts a clean, immediate setup failure into scattered incorrect behaviour, which is strictly worse: the run goes green often enough to be trusted and wrong often enough to mislead. If it appears in a committed configuration, treat it as a defect to remove rather than a setting to preserve. ## What the Apple half of the set needs instead There is no equivalent provisioning problem on Apple platforms, and pretending there is wastes time. The XCUITest driver reaches web content over the device's remote debugger itself, so no per-device executable exists to distribute and no engine-to-binary matrix has to be maintained. The variance moves elsewhere: - The build under test has to have opted its web views into debugging, which a release artefact commonly has not. - Real devices need Web Inspector enabled in their settings; simulators do not. - Where the debugger traffic cannot go direct, `remoteDebugProxy` names the endpoint it is routed through. - `appium:webviewConnectTimeout` absorbs a slow first connection on a loaded machine. So the fleet work on one platform is a supply of binaries, and on the other it is a supply of correctly configured builds and devices. Naming which one you are talking about is not pedantry here; it is the difference between two unrelated pieces of work. ## A worked example A dive-log app for scuba clubs runs its nightly hybrid suite against four Android phones and two iPhones. Over a month the Android job develops a one-in-four failure rate, always on the dive-site guide screen, always after the native navigation has succeeded. The suite has not changed. What changed is that two of the four phones took a System WebView update and the host still carries the single Chromedriver that suited them in the spring. The repair has two halves and neither is in the tests. On the Android side, drop the needed builds into a provisioned folder, point `appium:chromedriverExecutableDir` at it and enable web-view details collection so each session picks correctly. On the iPhones, which never had this failure, the standing requirement is different and unchanged: keep producing builds whose web views are debuggable and keep Web Inspector enabled on the hardware. ## Signatures worth recognising 1. Partial failure across otherwise identical Android phones points at engine drift, not at the suite. 2. A failure that appears only after native steps have passed points at the web channel, not at locators. 3. A whole-platform failure on Apple hardware that simulators never showed points at a device setting or a build, not at a binary.
- Why not simply pin every Android device in the set to one engine build?Because the engine updates through the store outside your control, so a pin is a claim you cannot enforce and it drifts silently. Supplying binaries for the builds that actually appear is the setup that survives; keeping every device frozen is a promise the platform will break for you.
- What is the Apple-side equivalent of provisioning binaries per device?There is none. The XCUITest driver needs no per-device executable, so the fleet work there is producing builds whose web views are debuggable and keeping Web Inspector enabled on real devices. The variance moves from host-side binaries to build configuration and device settings.
saying these in an interview costs you the question
- Assumes one Chromedriver build fits every Android device
- Thinks the OS release determines the web view engine build
- Relies on autodownload from an isolated runner with no egress
- Disables the build check across the fleet to make runs pass
- Expects Apple devices to need per-device binaries too