Skip to content

AndroidNodeFilter

Interface

Builder pattern for complex node queries.

AndroidNodeFilter provides a fluent builder interface for constructing complex queries to find nodes in the accessibility tree. All methods are chainable and return the filter instance.

Basic Usage
// Find a submit button
const button = screen.findAdvanced(f => f.isButton().hasText("Submit"));

// Find all editable text fields
const inputs = screen.filterAdvanced(f => f.isEditText().isEditable());

// Complex query with multiple conditions
const node = screen.findAdvanced(f =>
  f.isClickable()
   .hasPackageName("com.example.app")
   .anyParent(p => p.hasId("com.example:id/main_container"))
);

Class Matchers

Match nodes based on their Android class type.

isButton

Signature
isButton(): AndroidNodeFilter

Matches nodes with className 'android.widget.Button'.

Example
const buttons = screen.filterAdvanced(f => f.isButton());

isText

Signature
isText(): AndroidNodeFilter

Matches nodes with className 'android.widget.TextView'.

Example
const labels = screen.filterAdvanced(f => f.isText());

isImage

Signature
isImage(): AndroidNodeFilter

Matches nodes with className 'android.widget.ImageView'.

Example
const images = screen.filterAdvanced(f => f.isImage());

isEditText

Signature
isEditText(): AndroidNodeFilter

Matches nodes with className 'android.widget.EditText' (text input fields).

Example
const inputs = screen.filterAdvanced(f => f.isEditText());

isCheckBox

Signature
isCheckBox(): AndroidNodeFilter

Matches nodes with className 'android.widget.CheckBox'.

Example
const checkboxes = screen.filterAdvanced(f => f.isCheckBox());

isRadioButton

Signature
isRadioButton(): AndroidNodeFilter

Matches nodes with className 'android.widget.RadioButton'.

Example
const radios = screen.filterAdvanced(f => f.isRadioButton());

isSwitch

Signature
isSwitch(): AndroidNodeFilter

Matches nodes with className 'android.widget.Switch'.

Example
const switches = screen.filterAdvanced(f => f.isSwitch());

isSeekBar

Signature
isSeekBar(): AndroidNodeFilter

Matches nodes with className 'android.widget.SeekBar'.

Example
const sliders = screen.filterAdvanced(f => f.isSeekBar());

isViewGroup

Signature
isViewGroup(): AndroidNodeFilter

Matches nodes with className 'android.view.ViewGroup' (container elements).

Example
const containers = screen.filterAdvanced(f => f.isViewGroup());

is

Signature
is(className: string): AndroidNodeFilter

Matches nodes with a custom className.

ParameterTypeDescription
classNamestringFull Android class name to match
Example
const recyclers = screen.filterAdvanced(f => f.is("androidx.recyclerview.widget.RecyclerView"));

State Matchers

Match nodes based on their current state.

isClickable

Signature
isClickable(): AndroidNodeFilter

Matches nodes that are clickable.

Example
const clickables = screen.filterAdvanced(f => f.isClickable());

isScrollable

Signature
isScrollable(): AndroidNodeFilter

Matches nodes that are scrollable.

Example
const scrollView = screen.findAdvanced(f => f.isScrollable());
if (scrollView) {
  await scrollView.performAction(agent.constants.ACTION_SCROLL_DOWN);
}

isSelected

Signature
isSelected(): AndroidNodeFilter

Matches nodes that are currently selected.

Example
const selectedItem = screen.findAdvanced(f => f.isSelected());

isEditable

Signature
isEditable(): AndroidNodeFilter

Matches nodes that allow text editing.

Example
const editableInputs = screen.filterAdvanced(f => f.isEditText().isEditable());

Content Matchers

Match nodes based on their text content.

hasText

Signature
hasText(text: string): AndroidNodeFilter

Matches nodes with exact text content.

ParameterTypeDescription
textstringExact text to match
Example
const submitBtn = screen.findAdvanced(f => f.isButton().hasText("Submit"));

text

Signature
text(condition: (text: string | undefined) => boolean): AndroidNodeFilter

Matches nodes based on a custom text condition.

ParameterTypeDescription
condition(text: string | undefined) => booleanFunction to test the text
Contains
const priceNodes = screen.filterAdvanced(f => f.text(t => t?.includes("$") ?? false));
Starts with
const items = screen.filterAdvanced(f => f.text(t => t?.startsWith("Item") ?? false));

hasDescription

Signature
hasDescription(description: string): AndroidNodeFilter

Matches nodes with exact content description (accessibility label).

ParameterTypeDescription
descriptionstringExact description to match
Example
const closeBtn = screen.findAdvanced(f => f.hasDescription("Close"));

descriptionContains

Signature
descriptionContains(part: string): AndroidNodeFilter

Matches nodes whose description contains the given text.

ParameterTypeDescription
partstringText to search for in description
Example
const icons = screen.filterAdvanced(f => f.isImage().descriptionContains("icon"));

description

Signature
description(condition: (desc: string | undefined) => boolean): AndroidNodeFilter

Matches nodes based on a custom description condition.

ParameterTypeDescription
condition(desc: string | undefined) => booleanFunction to test the description
Example
const nodes = screen.filterAdvanced(f =>
  f.description(d => d?.toLowerCase().includes("button") ?? false)
);

hasChildWithText

Signature
hasChildWithText(text: string): AndroidNodeFilter

Matches nodes that have a direct child with the specified text.

ParameterTypeDescription
textstringText to find in children
Example
// Find containers that have a "Settings" label inside
const settingsSection = screen.findAdvanced(f =>
  f.isViewGroup().hasChildWithText("Settings")
);

Identity Matchers

Match nodes based on their identity attributes.

hasId

Signature
hasId(id: string): AndroidNodeFilter

Matches nodes with the specified viewId.

ParameterTypeDescription
idstringView ID to match (e.g., 'com.example:id/button')
Example
const header = screen.findAdvanced(f => f.hasId("com.example:id/header_title"));

hasPackageName

Signature
hasPackageName(packageName: string): AndroidNodeFilter

Matches nodes belonging to the specified package.

ParameterTypeDescription
packageNamestringPackage name to match
Example
// Only match nodes from a specific app
const appNodes = screen.filterAdvanced(f =>
  f.hasPackageName("com.example.myapp")
);

hasChildWithId

Signature
hasChildWithId(id: string): AndroidNodeFilter

Matches nodes that have a direct child with the specified viewId.

ParameterTypeDescription
idstringView ID to find in children
Example
// Find containers with specific child elements
const container = screen.findAdvanced(f =>
  f.hasChildWithId("com.example:id/item_icon")
);

Logical Operators

Combine multiple conditions using logical operators.

and

Signature
and(filterBuilder: (f: AndroidNodeFilter) => void): AndroidNodeFilter

Combines with another filter using AND logic. The node must match both filters.

ParameterTypeDescription
filterBuilder(f: AndroidNodeFilter) => voidFunction to build the additional filter
Example
// Find clickable buttons with specific text
const btn = screen.findAdvanced(f =>
  f.isButton().and(a => a.isClickable().hasText("Submit"))
);

or

Signature
or(filterBuilder: (f: AndroidNodeFilter) => void): AndroidNodeFilter

Combines with another filter using OR logic. The node must match either filter.

ParameterTypeDescription
filterBuilder(f: AndroidNodeFilter) => voidFunction to build the alternative filter
Match buttons OR clickable images
const clickables = screen.filterAdvanced(f =>
  f.isButton().or(o => o.isImage().isClickable())
);
Match multiple text options
const node = screen.findAdvanced(f =>
  f.hasText("OK").or(o => o.hasText("Confirm")).or(o => o.hasText("Yes"))
);

Hierarchy Matchers

Match nodes based on their position in the node hierarchy.

parent

Signature
parent(filterBuilder: (f: AndroidNodeFilter) => void): AndroidNodeFilter

Matches nodes whose immediate parent matches the given filter.

ParameterTypeDescription
filterBuilder(f: AndroidNodeFilter) => voidFunction to build the parent filter
Example
// Find text views inside a specific container
const labels = screen.filterAdvanced(f =>
  f.isText().parent(p => p.hasId("com.example:id/header"))
);

anyParent

Signature
anyParent(filterBuilder: (f: AndroidNodeFilter) => void): AndroidNodeFilter

Matches nodes that have any ancestor matching the given filter.

ParameterTypeDescription
filterBuilder(f: AndroidNodeFilter) => voidFunction to build the ancestor filter
Find items inside a specific list
const listItems = screen.filterAdvanced(f =>
  f.isText().anyParent(p => p.hasId("com.example:id/user_list"))
);
Find clickables inside a dialog
const dialogButtons = screen.filterAdvanced(f =>
  f.isClickable().anyParent(p => p.is("android.app.Dialog"))
);

Complex Examples

Find login button in a specific form
const loginBtn = screen.findAdvanced(f =>
  f.isButton()
   .hasText("Login")
   .isClickable()
   .anyParent(p => p.hasId("com.example:id/login_form"))
);
Find all product prices
const prices = screen.filterAdvanced(f =>
  f.isText()
   .text(t => /^\$\d+/.test(t || ""))
   .anyParent(p => p.hasId("com.example:id/product_card"))
);

for (const price of prices) {
  console.log("Price:", price.text);
}
Find first empty input field
const emptyInput = screen.findAdvanced(f =>
  f.isEditText()
   .isEditable()
   .text(t => !t || t.length === 0)
);

if (emptyInput) {
  await emptyInput.performAction(agent.constants.ACTION_CLICK);
  await agent.actions.writeText("Hello");
}
Find any confirmation button
const confirmBtn = screen.findAdvanced(f =>
  f.isButton()
   .isClickable()
   .or(o => o.hasText("OK"))
   .or(o => o.hasText("Confirm"))
   .or(o => o.hasText("Yes"))
   .or(o => o.hasText("Accept"))
);