skip to content

In Appium, which web-view handle do you switch into when a pharmacy app lists several, on Android and iOS?

level: seniorimportance: should knowfreq 45%

answer

  1. names only, until you ask for detail
  2. match on title or URL
  3. mobile: getContexts is the richer read
  4. Android suffix is a hosting package
  5. Apple page ids change every run

basics

~20 s

Pick by evidence, not by position: read the per-view detail mobile: getContexts returns and match on the view's title or URL. Android names a handle after the hosting process, while iOS names it with a page id that changes each run.

solid answer

~40 s

The plain listing gives names only, so with several web views you cannot tell the refill-reminder app's co-pay page from an embedded advert frame. `mobile: getContexts` — an execute method on the Android drivers and on the XCUITest driver — returns the same contexts with detail such as each view's title and URL, and matching on those is the stable choice. On Android the handle's suffix is the package of the process hosting the view, and `appium:enableWebviewDetailsCollection` and `appium:ensureWebviewsHavePages` govern how much detail is gathered and whether page-less views are listed at all. On iOS several page ids can belong to one app, `appium:additionalWebviewBundleIds` brings in views hosted by other bundles, `appium:includeSafariInWebviews` adds Safari's pages, and `appium:webviewConnectTimeout` gives detection time. Never hardcode an Apple page id.

code

bash · 4 lines
bash
BASE=http://127.0.0.1:4723
SID=$(cat session-id.txt)
printf '{"script": "mobile: getContexts", "args": []}' > req.json
curl -s -X POST $BASE/session/$SID/execute/sync -H 'Content-Type: application/json' -d @req.json

go deeper

for a junior

Know that the list can hold more than one WEBVIEW_ handle, and that taking the first one is a guess rather than a strategy.

for a middle

Explain what mobile: getContexts adds over the plain listing, and which capabilities decide whether an Android page-less view or an Apple Safari page appears at all.

for a senior

Show a selection rule that survives a device fleet: match on title or URL, fail loudly with the listing attached, and never carry an Apple page id between runs.

for a principal

Own the cross-platform contract: one helper returning the intended view on both platforms, with the Android and Apple discovery differences hidden behind it and covered by tests.

## When the list stops being obvious On a simple hybrid screen the contexts list holds two entries and the choice makes itself. Real apps are not that tidy. The pharmacy refill-reminder app's co-pay screen can carry an embedded payment frame from the insurer, a help panel, and a pharmacy-network advert, each of which may surface as its own handle; on Apple devices the remote debugger can report several pages for one application, and other bundles' views can be pulled in deliberately. Picking the first `WEBVIEW_` handle in the list is then a coin toss that passes on a developer's simulator and fails on a device lane. ## What the plain listing withholds `GET /session/:sessionId/contexts` answers with names and nothing else. Names are enough to tell native from web, and on Android they carry a hosting package, but they never tell you which page a handle is showing. That is the gap `mobile: getContexts` fills: an execute method declared by the Android drivers and by the XCUITest driver, it returns the same set of contexts with per-view detail such as titles and URLs. Selection logic should read that detail and match on it, because a title or a URL is a property of the page you actually want, while an index in a list is a property of the order the driver happened to report. ## The Android side of the problem - The handle's suffix is the package of the process hosting the view, so two different processes rendering web content produce two visibly different handles. - `appium:enableWebviewDetailsCollection` controls whether the extra per-view detail is gathered, which is what makes title-and-URL matching possible. - `appium:ensureWebviewsHavePages` keeps handles with no attached page out of the list, so a picker cannot select a context that has nothing to drive. - `appium:webviewDevtoolsPort` addresses the port side of detection when the defaults do not fit the device. The practical consequence: on Android a suffix match is a legitimate first filter, and detail matching narrows what is left. ## The Apple side of the problem - The handle's suffix is a numeric page id issued when the remote debugger attaches, so it is meaningful only inside the current session and worthless in the next one. - `appium:includeSafariInWebviews` adds Safari's own pages to the listing, which is useful deliberately and confusing accidentally. - `appium:additionalWebviewBundleIds` brings in views hosted by bundles other than the app under test. - `appium:webviewConnectTimeout` gives detection more time before the driver concludes there is nothing to list. The practical consequence: on iOS there is no stable name to match, so the selection rule must be detail-driven by construction rather than by preference. ## A selection rule that survives a fleet 1. List the contexts at the moment of use, never at session start, because the interesting view may not exist yet. 2. Filter to handles beginning with `WEBVIEW_`; keep the native handle out of the candidate set. 3. Ask the driver for detail with `mobile: getContexts` and match on the title or URL that identifies the refill-reminder co-pay page. 4. On Android, narrow first by the hosting package when the app owns its web view; on iOS, skip that step entirely and rely on the detail. 5. If exactly one candidate matches, post it. If none matches, fail immediately with the full list in the message rather than falling back to the first entry. 6. Never persist a chosen handle between runs, and never write an Apple page id into test data or a configuration file. ## Failing well when nothing matches A selection helper that silently picks the first candidate turns a configuration problem into an intermittent assertion failure three steps later. A helper that raises with the whole listing attached turns the same problem into a one-line diagnosis. That difference matters most on shared device lanes, where the person reading the failure did not run it and cannot reproduce it on demand. Two failure shapes are worth distinguishing in the message. An empty candidate set means no web view was detected at all, which points at web-view debug wiring rather than at selection. A non-empty set with no match means detection worked and the expectation is wrong — the page moved, the title changed, or the run is on the wrong platform branch of the helper. ## What not to conclude Selection is not a substitute for wiring, and it is not a locator strategy. Once the correct handle is posted, finding elements inside the page is a separate concern with its own rules. The job here ends at the moment the right surface is current — and the whole reason it is a senior question is that the Android and Apple halves of it need different rules to reach that same moment.

  • The refill-reminder app's Android context list includes a handle with no page behind it. What is that?
    A web-view process the driver can see but that has no attached page to drive, so switching into it gives you nothing to find. `appium:ensureWebviewsHavePages` keeps such handles out of the listing, which matters whenever a picker would otherwise take the first `WEBVIEW_` entry it sees.
  • Why is `appium:includeSafariInWebviews` an Apple-only concern for handle selection?
    Because on iOS Safari's own pages can be surfaced as web-view contexts, so a session driving the refill-reminder app can suddenly see handles that do not belong to it. Android has no equivalent: its handles come from the packages hosting web views, so nothing outside the app's processes joins the list by default.

saying these in an interview costs you the question

  • Takes the first WEBVIEW_ handle in the list and hopes
  • Hardcodes an Apple page id copied from a passing run
  • Assumes one app can expose only one web view
  • Expects titles and URLs from the plain listing, which carries names only
  • Applies the Android package-suffix rule to iOS handles too
  • Falls back to any candidate instead of failing with the full list