skip to content

In Appium, what does `appium:printPageSourceOnFindFailure` do, and what does it cost?

level: middleimportance: should knowfreq 36%

answer

  1. a debugging capability, not a wait
  2. server log, not the test exception
  3. one full hierarchy dump per failed find
  4. different XML on Android and iOS

basics

~20 s

appium:printPageSourceOnFindFailure makes the Appium server write the whole page-source hierarchy into its log whenever a find fails. Each dump costs a full hierarchy snapshot, so a suite that misses often runs slower and logs far more.

solid answer

~50 s

`appium:printPageSourceOnFindFailure` is a debugging capability: switch it on and, whenever a find command fails, the Appium server writes the screen's whole element hierarchy as XML into **its own log** beside the failure. It is declared by the base driver, so the Android drivers and the XCUITest driver both honour it — but the document is not the same on the two platforms. The Android dump is the UiAutomator2 driver's view hierarchy, carrying names such as `resource-id` and `content-desc`; the iOS dump is XML derived from WebDriverAgent's snapshot, made of `XCUIElementType` nodes carrying `name` and `label`. The cost is a full hierarchy traversal plus a large log block **per failed find**, which is why it is opt-in: leave it off for routine runs and switch it on for a targeted re-run of the test that failed.

go deeper

for a junior

Know that it is a capability you switch on for debugging, and that the hierarchy it prints goes into the Appium server's log rather than into the test's own failure message.

for a middle

Explain that the base driver declares it, so the Android drivers and the XCUITest driver both honour it, but the XML each one prints is built from a different hierarchy with different names.

for a senior

Show judgment about when to pay for it: a targeted re-run rather than a fleet-wide default, because every failed find buys a full hierarchy traversal and a large block of log.

for a principal

Decide which diagnostics are always-on and which are opt-in per run, and be able to state what that choice costs in run time and log volume across a whole device fleet.

## What the capability switches on `appium:printPageSourceOnFindFailure` is a **diagnostic**, not a timing control. When it is set and a find command fails, the Appium server writes the current page source — the whole XML rendering of the screen's element hierarchy — into **its own log**, next to the failure. Nothing about the search itself changes: the same query runs for the same length of time and fails the same way. All the capability buys is evidence. It is one of the small set of capabilities Appium's base driver declares rather than a driver-specific one, so it applies whichever platform driver is handling the session — the Android drivers and the XCUITest driver alike. It is not a W3C standard capability name, so it is sent prefixed, as `appium:printPageSourceOnFindFailure`, in the session's capabilities. Two things about *when* the dump happens are worth being precise about. A find in Appium is not a single instantaneous lookup: while the session's find window is open the server re-issues the query on a roughly **500 ms** cadence, so a failed find represents repeated attempts rather than one. And the hierarchy that lands in the log is the screen as it stood **at the point the command reported failure**, not as it stood when the command was first issued. If the app moved on during the search, the dump shows where it ended up. ## The dump is not the same document on Android and on iOS | | Android, via the UiAutomator2 driver | iOS, via the XCUITest driver | |---|---|---| | Where the XML comes from | the driver's rendering of the current view hierarchy | XML derived from WebDriverAgent's element snapshot | | What the nodes are called | Android widget class names | `XCUIElementType` names | | What you scan for | `resource-id`, `content-desc`, `text` | `name`, `label`, `value` | So the capability is portable and its output is not. A helper that greps an Android dump for a `resource-id` finds nothing in an Apple one, and a locator inferred by eye from one platform's dump does not transfer to the other. That matters most when the same test runs on both: the failure looks identical in the report and the evidence underneath it does not. ## What it costs - Every failed find pays for a **full hierarchy traversal**, on top of the search that already failed. - The deeper and busier the screen, the more that costs — a dense list, or a screen with many nodes off-view, is the expensive case on either platform. - Each dump writes a large block of XML into the server log, so log volume grows with the number of misses, not with the number of tests. - A step that deliberately checks something is **absent** ends on a failed find too, so it pays for a dump every time it does the right thing. - On a suite that is currently red in many places the cost compounds exactly when you can least afford the run to be slower. That is why it is opt-in. A session that does not set the capability never dumps, and the usual pattern is off for routine runs and on deliberately. ## Using it well 1. Turn it on for a **targeted re-run** of the failing test, on the same platform and the same device where the failure happened — a hierarchy from a different device is a different screen. 2. Collect the **server** log for that run. The XML is not attached to the exception the client raises, so a test report on its own will never show it. 3. Read the dump as evidence about the screen, not about the locator: it says what was present at failure time, which separates *the element was never there* from *the element was there under a different name*. 4. Turn it back off, or confine it to a debugging profile, once you have what you need. ## What it does not give you It does not say why the element was missing, only what the hierarchy held instead. It does not make the find wait longer or try harder, and it does not change the outcome of the command in any way. It does not travel back to the client, so nothing in a test can assert on it. And it is faithful only to what the driver could reach: on a screen the driver cannot fully see, the dump describes the driver's view, which is not always what a person holding the device would describe. Treat it as the first artefact to reach for on an unexplained find failure, and as something you switch on, use, and switch off again — a capability with a real running cost that happens to be cheap in the one situation where you actually need it.

  • Where does the dumped hierarchy end up, and where does it not?
    In the Appium server's own log, at the point the find failed. It is not attached to the exception the client raises, so a test report shows only the find failure. If the failure happens somewhere you do not have the server output to hand, the capability buys you nothing until you have that log from that run.
  • Would you leave `appium:printPageSourceOnFindFailure` on for a whole suite?
    Usually no. Every failed find pays for a full hierarchy dump and writes a large block into the log, and a step that deliberately checks an element is gone ends on a failed find as well. The normal pattern is off by default and on for a targeted re-run of the failing test, on the same platform and device where it failed.

saying these in an interview costs you the question

  • Thinks the dumped XML appears in the test's exception message
  • Expects the same document on Android and iOS
  • Treats it as a wait or retry setting rather than a diagnostic
  • Leaves it on everywhere and blames the slowdown on the app
  • Assumes the dump shows the screen as it was when the command started
  • Reuses a locator read off one platform's dump on the other platform