website/docs/mcp/selectors.md
The WebdriverIO MCP server supports multiple selector strategies for locating elements on web pages and mobile apps.
:::info
For comprehensive selector documentation including all WebdriverIO selector strategies, see the main Selectors guide. This page focuses on selectors commonly used with the MCP server.
:::
For browser automation, the MCP server supports all standard WebdriverIO selectors. The most commonly used include:
| Selector | Example | Description |
|---|---|---|
| CSS | #login-button, .submit-btn | Standard CSS selectors |
| XPath | //button[@id='submit'] | XPath expressions |
| Text | button=Submit, a*=Click | WebdriverIO text selectors |
| ARIA | aria/Submit Button | Accessibility name selectors |
| Test ID | [data-testid="submit"] | Recommended for testing |
For detailed examples and best practices, see the Selectors documentation.
Mobile selectors work with both iOS and Android platforms through Appium.
Accessibility IDs are the most reliable cross-platform selector. They work on both iOS and Android and are stable across app updates.
# Syntax
~accessibilityId
# Examples
~loginButton
~submitForm
~usernameField
:::tip Best Practice Always prefer accessibility IDs when available. They provide:
UiAutomator selectors are powerful and fast for Android.
# By Text
android=new UiSelector().text("Login")
# By Partial Text
android=new UiSelector().textContains("Log")
# By Resource ID
android=new UiSelector().resourceId("com.example:id/login_button")
# By Class Name
android=new UiSelector().className("android.widget.Button")
# By Description (Accessibility)
android=new UiSelector().description("Login button")
# Combined Conditions
android=new UiSelector().className("android.widget.Button").text("Login")
# Scrollable Container
android=new UiScrollable(new UiSelector().scrollable(true)).scrollIntoView(new UiSelector().text("Item"))
Resource IDs provide stable element identification on Android.
# Full Resource ID
id=com.example.app:id/login_button
# Partial ID (app package inferred)
id=login_button
XPath works on Android but is slower than UiAutomator.
# By Class and Text
//android.widget.Button[@text='Login']
# By Resource ID
//android.widget.EditText[@resource-id='com.example:id/username']
# By Content Description
//android.widget.ImageButton[@content-desc='Menu']
# Hierarchical
//android.widget.LinearLayout/android.widget.Button[1]
iOS Predicate Strings are fast and powerful for iOS automation.
# By Label
-ios predicate string:label == "Login"
# By Partial Label
-ios predicate string:label CONTAINS "Log"
# By Name
-ios predicate string:name == "loginButton"
# By Type
-ios predicate string:type == "XCUIElementTypeButton"
# By Value
-ios predicate string:value == "ON"
# Combined Conditions
-ios predicate string:type == "XCUIElementTypeButton" AND label == "Login"
# Visibility
-ios predicate string:label == "Login" AND visible == 1
# Case Insensitive
-ios predicate string:label ==[c] "login"
Predicate Operators:
| Operator | Description |
|---|---|
== | Equals |
!= | Not equals |
CONTAINS | Contains substring |
BEGINSWITH | Starts with |
ENDSWITH | Ends with |
LIKE | Wildcard match |
MATCHES | Regex match |
AND | Logical AND |
OR | Logical OR |
iOS Class Chains provide hierarchical element location with good performance.
# Direct Child
-ios class chain:**/XCUIElementTypeButton[`label == "Login"`]
# Any Descendant
-ios class chain:**/XCUIElementTypeButton
# By Index
-ios class chain:**/XCUIElementTypeCell[3]
# Combined with Predicate
-ios class chain:**/XCUIElementTypeButton[`name == "submit" AND visible == 1`]
# Hierarchical
-ios class chain:**/XCUIElementTypeTable/XCUIElementTypeCell[`label == "Settings"`]
# Last Element
-ios class chain:**/XCUIElementTypeButton[-1]
XPath works on iOS but is slower than predicate strings.
# By Type and Label
//XCUIElementTypeButton[@label='Login']
# By Name
//XCUIElementTypeTextField[@name='username']
# By Value
//XCUIElementTypeSwitch[@value='1']
# Hierarchical
//XCUIElementTypeTable/XCUIElementTypeCell[1]
When writing tests that need to work on both iOS and Android, use this priority order:
# Works on both platforms
~loginButton
When accessibility IDs aren't available, use platform-specific selectors:
Android:
android=new UiSelector().text("Login")
iOS:
-ios predicate string:label == "Login"
XPath works on both platforms but with different element types:
Android:
//android.widget.Button[@text='Login']
iOS:
//XCUIElementTypeButton[@label='Login']
| Type | Description |
|---|---|
android.widget.Button | Button |
android.widget.EditText | Text input |
android.widget.TextView | Text label |
android.widget.ImageView | Image |
android.widget.ImageButton | Image button |
android.widget.CheckBox | Checkbox |
android.widget.RadioButton | Radio button |
android.widget.Switch | Toggle switch |
android.widget.Spinner | Dropdown |
android.widget.ListView | List view |
android.widget.RecyclerView | Recycler view |
android.widget.ScrollView | Scroll container |
| Type | Description |
|---|---|
XCUIElementTypeButton | Button |
XCUIElementTypeTextField | Text input |
XCUIElementTypeSecureTextField | Password input |
XCUIElementTypeStaticText | Text label |
XCUIElementTypeImage | Image |
XCUIElementTypeSwitch | Toggle switch |
XCUIElementTypeSlider | Slider |
XCUIElementTypePicker | Picker wheel |
XCUIElementTypeTable | Table view |
XCUIElementTypeCell | Table cell |
XCUIElementTypeCollectionView | Collection view |
XCUIElementTypeScrollView | Scroll view |
# Good - Stable accessibility ID
~loginButton
# Bad - Fragile XPath with indices
//div[3]/form/button[2]
# Good - Specific CSS with test ID
[data-testid="submit-button"]
# Bad - Class that might change
.btn-primary-lg-v2
# Good - UiAutomator with resource ID
android=new UiSelector().resourceId("com.app:id/submit")
# Bad - Text that might be localized
android=new UiSelector().text("Submit")
document.querySelector('your-selector')get_visible_elementsThe MCP server's get_visible_elements tool returns multiple selector strategies for each element:
Ask Claude: "Get all visible elements on the screen"
This returns elements with pre-generated selectors you can use directly.
For more control over element discovery:
# Get only images and visual elements
Get visible elements with elementType "visual"
# Get elements with their coordinates for layout debugging
Get visible elements with includeBounds enabled
# Get the next 20 elements (pagination)
Get visible elements with limit 20 and offset 20
# Include layout containers for debugging
Get visible elements with includeContainers enabled
The tool returns a paginated response:
{
"total": 42,
"showing": 20,
"hasMore": true,
"elements": [...]
}
get_accessibility (Browser Only)For browser automation, the get_accessibility tool provides semantic information about page elements:
# Get all named accessibility nodes
Get accessibility tree
# Filter to only buttons and links
Get accessibility tree filtered to button and link roles
# Get next page of results
Get accessibility tree with limit 50 and offset 50
This is useful when get_visible_elements doesn't return expected elements, as it queries the browser's native accessibility API.