WebView locator patterns
One control per pattern. Load it in a WebView and dump the accessibility tree. Each heading matches a section in the blog post.
1. Labelled text field (label + hint + error)
name from <label>; hint is a description, not a name; error announced via role=alert
We only use this for receipts.
Enter a valid email address.
2. Password field with show/hide
password=true + masked value; the toggle is an icon-only button
3. Checkbox group, radio group, switch
each option is its own CheckBox / RadioButton; the fieldset legend is not a control name
4. Native select and custom combobox
native select is one node whose text is the chosen option; a custom listbox is many nodes
5. Icon-only buttons
no visible text — the name must come from aria-label
6. Tabs
tablist / tab / tabpanel; the selected tab is exposed by aria-selected
Your balance is 1,250.
No recent activity.
7. Disclosure / accordion
a button with aria-expanded controlling a region
Usually within one business day.
8. Dialog (native and custom)
custom role="dialog" surfaces as android.app.Dialog on WebView 140; on WebView 115 only its contents appeared
Delete recipient
This cannot be undone.
9. List with per-row actions
duplicate action names — scope to the row, or make the names unique
-
Transfer to Alice
-
Transfer to Bob
10. Toast (live region)
aria-live; the message is a node only while it exists, and it fires an event
11. Data table (sortable, caption, scopes)
caption/headers; sort state via aria-sort; each cell is its own node
Exchange rates (SGD)
| Currency | Rate |
| USD | 1.34 |
| MYR | 0.29 |
| EUR | 1.45 |
12. Incremental list (Load more)
only appended items exist in the tree; a windowed list would additionally drop scrolled-away rows
13. Canvas chart (opaque to the tree)
canvas has no accessible nodes; provide a text alternative or a table
Balance trend: up 12% over 30 days.
14. Async validation and delayed content
content appears after a delay; error appears after a request settles