skip to content

In Appium, which requests list a session's contexts and switch into one on Android and iOS?

level: juniorimportance: should knowfreq 58%

answer

  1. plural lists, singular switches
  2. GET contexts, POST context
  3. same routes on both platforms
  4. mobile: getContexts adds titles and URLs
  5. handle values diverge, endpoints do not

basics

~10 s

Two requests do it, and they are the same on both platforms: GET /session/:sessionId/contexts returns the available handles, and POST /session/:sessionId/context with a name enters one. Only the handle values differ per platform.

solid answer

~40 s

`GET /session/:sessionId/contexts` returns the handles the driver can serve right now — always the native one, `NATIVE_APP`, plus a `WEBVIEW_` handle for each detected web view. `POST /session/:sessionId/context` carries the chosen handle as `name` and makes it the surface every later command is answered from, until you switch again. Both requests behave identically on Android and iOS; what diverges is the handle values, since Android's `WEBVIEW_` handle ends in the package of the process hosting the view and Apple's ends in a numeric page id. Drivers also expose `mobile: getContexts`, an execute method on the Android drivers and on the XCUITest driver, which returns the same contexts with extra detail such as titles and URLs. In the refill-reminder app you list, pick, post, and only then look for the co-pay page's fields.

go deeper

for a junior

Know both requests by name and shape: the plural path lists the handles, the singular path takes the one you want. Add that the pair is the same on Android and iOS.

for a middle

Explain what the driver does with the posted handle, which tree answers finds afterwards, and when mobile: getContexts is worth calling instead of the plain listing.

for a senior

Talk about where these calls belong in a suite so a hybrid flow never guesses its surface, and how discovery differs when Android names a package and iOS a page id.

for a principal

Frame context as session state the framework owns explicitly, with one discovery helper covering both platforms rather than per-platform snippets copied through the suite.

## Contexts are the session's surface selector An Appium session drives one surface at a time. On both Android and iOS a session starts on the native one, whose handle is `NATIVE_APP`. When the app under test also renders web content — the pharmacy refill-reminder app's insurance co-pay page inside an embedded web view — that content is reachable only through a second handle. Choosing between them is exactly what the two context requests do, and they are ordinary protocol commands: not capabilities sent at session start, and not driver execute methods. ## The plural path lists, the singular path switches - `GET /session/:sessionId/contexts` returns the handles available at this moment, as a list of strings. It changes nothing and is cheap enough to call at any screen boundary. - `POST /session/:sessionId/context` carries one handle as `name`. From the moment it returns, finds, source reads and element interactions are answered from that surface. The plural-versus-singular pairing is worth memorising, because mixing them is the commonest beginner mistake: a POST to the plural path is not a switch, and reading the singular path is not a listing. Both routes are spelled with `:sessionId`, the session identifier the server handed back when the session was created. ## What the list actually contains The first entry a healthy session shows is `NATIVE_APP`. After that come the web views the driver has detected, each named with the `WEBVIEW_` prefix. The list is a snapshot: a web view that the refill-reminder app has not opened yet is not in it, and one that has been destroyed drops out. That is why the list is read at the point of use rather than once at session start. ## The richer read: mobile: getContexts `mobile: getContexts` is an execute method declared by the Android drivers — UiAutomator2 and Espresso inherit it from `appium-android-driver` — and by the XCUITest driver. It answers the same question with more detail, including each view's title and URL, which is what you need when several web views are listed and their names alone cannot tell you which is the co-pay page. It does not replace the plain listing; it is the detailed form of the same question, and it travels as an execute method rather than as its own route. ## Where the platforms diverge, and where they do not | | Android (UiAutomator2 or Espresso) | Apple (XCUITest) | |---|---|---| | listing request | `GET /session/:sessionId/contexts` | `GET /session/:sessionId/contexts` | | switching request | `POST /session/:sessionId/context` | `POST /session/:sessionId/context` | | native handle | `NATIVE_APP` | `NATIVE_APP` | | web handle suffix | the package of the process hosting the view | a numeric page id assigned at runtime | The routes are identical; the values are not. A test that hardcodes an Android-shaped handle and runs on an Apple device fails at the switch, not at the find, and the error is much easier to read for it. ## A refill-reminder flow that reads correctly 1. Drive the native reminder list and tap **Refill now** — still on `NATIVE_APP`. 2. List the contexts and keep the result; it is the evidence for whatever happens next. 3. Choose the `WEBVIEW_` handle that belongs to the co-pay page. 4. Post that handle to the singular context route. 5. Assert the page's fields, complete the co-pay step, and read whatever the page confirms. 6. Post `NATIVE_APP` to return, then continue with the native confirmation screen. ## Mistakes worth naming - Posting to the plural path, or expecting the listing to change the current surface. - Assuming the endpoints differ between Android and iOS; they do not, only the handles do. - Treating `mobile: getContexts` as a replacement for the listing route rather than its detailed sibling. - Listing once at session start and reusing the result later, when the web view of interest did not exist yet. - Forgetting the return trip, so later native steps run against a page that has no such elements. A junior who can name both requests, say which is which, and add that the pair is identical on Android and iOS while the handle values are not, has given the complete answer to this question.

  • How do you find out which context the refill-reminder session is in right now?
    Read it back rather than remembering it. Clients expose a current-context read, and `mobile: getContexts` on the Android drivers or the XCUITest driver shows the full set so you can compare. Asserting the surface at a screen boundary is far cheaper than debugging a find that failed three steps later.
  • Why is switching a runtime command rather than something you configure at session start?
    Because the surface changes as the app runs. The refill-reminder app is native on its reminder list and web on its co-pay page, so the session has to move between them mid-flow. `POST /session/:sessionId/context` does that without restarting anything, which is why the flow keeps the state it has reached.

saying these in an interview costs you the question

  • Posts to the plural contexts path expecting it to switch
  • Believes Android and iOS use different context endpoints
  • Thinks switching requires ending the session and starting a new one
  • Assumes mobile: getContexts replaces the standard contexts listing
  • Expects the list to include web views the app has not opened yet