UiSelector.java revision a46ac3504426564954292b13380120e8cc6b1527
1e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu/* 2e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * Copyright (C) 2012 The Android Open Source Project 3e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * 4e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * Licensed under the Apache License, Version 2.0 (the "License"); 5e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * you may not use this file except in compliance with the License. 6e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * You may obtain a copy of the License at 7e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * 8e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * http://www.apache.org/licenses/LICENSE-2.0 9e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * 10e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * Unless required by applicable law or agreed to in writing, software 11e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * distributed under the License is distributed on an "AS IS" BASIS, 12e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * See the License for the specific language governing permissions and 14e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * limitations under the License. 15e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu */ 16e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 17e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhupackage com.android.uiautomator.core; 18e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 19e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport android.util.SparseArray; 20e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhuimport android.view.accessibility.AccessibilityNodeInfo; 21e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 22e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu/** 23e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * This class provides the mechanism for tests to describe the UI elements they 24e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * intend to target. A UI element has many properties associated with it such as 253d50587be8ff021369c90554d814839335b445b0Adam Momtaz * text value, content-description, class name and multiple state information like 263d50587be8ff021369c90554d814839335b445b0Adam Momtaz * selected, enabled, checked etc. Additionally UiSelector allows targeting of UI 273d50587be8ff021369c90554d814839335b445b0Adam Momtaz * elements within a specific display hierarchies to distinguish similar elements 283d50587be8ff021369c90554d814839335b445b0Adam Momtaz * based in the hierarchies they're in. 29e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu */ 304ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtazpublic class UiSelector { 31e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_NIL = 0; 32e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_TEXT = 1; 33e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_START_TEXT = 2; 34e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_CONTAINS_TEXT = 3; 35e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_CLASS = 4; 36e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_DESCRIPTION = 5; 37e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_START_DESCRIPTION = 6; 38e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_CONTAINS_DESCRIPTION = 7; 39e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_INDEX = 8; 40e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_INSTANCE = 9; 41e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_ENABLED = 10; 42e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_FOCUSED = 11; 43e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_FOCUSABLE = 12; 44e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_SCROLLABLE = 13; 45e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_CLICKABLE = 14; 46e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_CHECKED = 15; 47e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_SELECTED = 16; 48e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_ID = 17; 49e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_PACKAGE_NAME = 18; 50e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_CHILD = 19; 51e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_CONTAINER = 20; 52e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_PATTERN = 21; 53e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_PARENT = 22; 54e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu static final int SELECTOR_COUNT = 23; 55e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 56e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private SparseArray<Object> mSelectorAttributes = new SparseArray<Object>(); 57e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 584ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz public UiSelector() { 59e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 60e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 613d50587be8ff021369c90554d814839335b445b0Adam Momtaz UiSelector(UiSelector selector) { 623d50587be8ff021369c90554d814839335b445b0Adam Momtaz mSelectorAttributes = selector.cloneSelector().mSelectorAttributes; 63e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 64e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 653d50587be8ff021369c90554d814839335b445b0Adam Momtaz protected UiSelector cloneSelector() { 664ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz UiSelector ret = new UiSelector(); 67e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu ret.mSelectorAttributes = mSelectorAttributes.clone(); 683d50587be8ff021369c90554d814839335b445b0Adam Momtaz if(hasChildSelector()) 693d50587be8ff021369c90554d814839335b445b0Adam Momtaz ret.mSelectorAttributes.put(SELECTOR_CHILD, new UiSelector(getChildSelector())); 703d50587be8ff021369c90554d814839335b445b0Adam Momtaz if(hasParentSelector()) 713d50587be8ff021369c90554d814839335b445b0Adam Momtaz ret.mSelectorAttributes.put(SELECTOR_PARENT, new UiSelector(getParentSelector())); 723d50587be8ff021369c90554d814839335b445b0Adam Momtaz if(hasPatternSelector()) 733d50587be8ff021369c90554d814839335b445b0Adam Momtaz ret.mSelectorAttributes.put(SELECTOR_PATTERN, new UiSelector(getPatternSelector())); 74e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return ret; 75e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 76e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 774ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz static UiSelector patternBuilder(UiSelector selector) { 78e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if(!selector.hasPatternSelector()) { 794ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz return new UiSelector().patternSelector(selector); 80e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 81e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return selector; 82e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 83e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 844ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz static UiSelector patternBuilder(UiSelector container, UiSelector pattern) { 854ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz return new UiSelector( 864ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz new UiSelector().containerSelector(container).patternSelector(pattern)); 87e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 88e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 89a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz /** 90a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Set the search criteria to match the visible text displayed 91a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * for a widget (for example, the text label to launch an app). 92a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 93a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * The text for the widget must match exactly 94a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * with the string in your input argument. 95a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Matching is case-sensitive. 96a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 97a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @param text Value to match 98a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @return UiSelector with the specified search criteria 99a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz */ 1004ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz public UiSelector text(String text) { 101e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return buildSelector(SELECTOR_TEXT, text); 102e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 103e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 104a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz /** 105a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Text property is usually the widget's visible text on the display. 106a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 107a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Adding this to the search criteria indicates that the search performed 108a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * should match a widget with text value starting with the text parameter. 109a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 110a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * The matching will be case-insensitive. 111a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 112a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @param text 113a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @return UiSelector with this added search criterion 114a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz */ 1154ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz public UiSelector textStartsWith(String text) { 116e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return buildSelector(SELECTOR_START_TEXT, text); 117e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 118e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 119a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz /** 120a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Set the search criteria to match the visible text displayed 121a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * for a widget (for example, the text label to launch an app). 122a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 123a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * The text for the widget must contain the string in 124a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * your input argument. Matching is case-sensitive. 125a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 126a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @param text Value to match 127a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @return UiSelector with the specified search criteria 128a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz */ 1294ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz public UiSelector textContains(String text) { 130e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return buildSelector(SELECTOR_CONTAINS_TEXT, text); 131e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 132e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 133a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz /** 134a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Set the search criteria to match the class property 135a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * for a widget (for example, "android.widget.Button"). 136a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 137a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @param className Value to match 138a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @return UiSelector with the specified search criteria 139a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz */ 1404ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz public UiSelector className(String className) { 141e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return buildSelector(SELECTOR_CLASS, className); 142e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 143e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 144a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz /** 145a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Set the search criteria to match the content-description 146a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * property for a widget. 147a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 148a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * The content-description is typically used 149a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * by the Android Accessibility framework to 150a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * provide an audio prompt for the widget when 151a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * the widget is selected. The content-description 152a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * for the widget must match exactly 153a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * with the string in your input argument. 154a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 155a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Matching is case-sensitive. 156a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 157a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @param desc Value to match 158a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @return UiSelector with the specified search criteria 159a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz */ 1604ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz public UiSelector description(String desc) { 161e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return buildSelector(SELECTOR_DESCRIPTION, desc); 162e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 163e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 164a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz /** 165a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Set the search criteria to match the content-description 166a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * property for a widget. 167a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 168a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * The content-description is typically used 169a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * by the Android Accessibility framework to 170a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * provide an audio prompt for the widget when 171a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * the widget is selected. The content-description 172a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * for the widget must start 173a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * with the string in your input argument. 174a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 175a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Matching is case-insensitive. 176a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 177a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @param desc Value to match 178a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @return UiSelector with the specified search criteria 179a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz */ 1804ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz public UiSelector descriptionStartsWith(String desc) { 181e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return buildSelector(SELECTOR_START_DESCRIPTION, desc); 182e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 183e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 184a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz /** 185a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Set the search criteria to match the content-description 186a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * property for a widget. 187a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 188a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * The content-description is typically used 189a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * by the Android Accessibility framework to 190a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * provide an audio prompt for the widget when 191a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * the widget is selected. The content-description 192a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * for the widget must contain 193a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * the string in your input argument. 194a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 195a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Matching is case-insensitive. 196a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 197a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @param desc Value to match 198a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @return UiSelector with the specified search criteria 199a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz */ 2004ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz public UiSelector descriptionContains(String desc) { 201e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return buildSelector(SELECTOR_CONTAINS_DESCRIPTION, desc); 202e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 203e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 204a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz /** 205a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Set the search criteria to match the widget by its node 206a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * index in the layout hierarchy. 207a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 208a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * The index value must be 0 or greater. 209a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 210a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Using the index can be unreliable and should only 211a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * be used as a last resort for matching. Instead, 212a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * consider using the {@link #instance(int)} method. 213a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 214a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @param index Value to match 215a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @return UiSelector with the specified search criteria 216a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz */ 2174ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz public UiSelector index(final int index) { 218e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return buildSelector(SELECTOR_INDEX, index); 219e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 220e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 221a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz /** 222a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Set the search criteria to match the 223a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * widget by its instance number. 224a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 225a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * The instance value must be 0 or greater, where 226a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * the first instance is 0. 227a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 228a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * For example, to simulate a user click on 229a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * the third image that is enabled in a UI screen, you 230a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * could specify a a search criteria where the instance is 231a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 2, the {@link #className(String)} matches the image 232a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * widget class, and {@link #enabled(boolean)} is true. 233a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * The code would look like this: 234a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * <code> 235a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * new UiSelector().className("android.widget.ImageView") 236a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * .enabled(true).instance(2); 237a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * </code> 238a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 239a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @param instance Value to match 240a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @return UiSelector with the specified search criteria 241a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz */ 2424ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz public UiSelector instance(final int instance) { 243e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return buildSelector(SELECTOR_INSTANCE, instance); 244e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 245e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 246a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz /** 247a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Set the search criteria to match widgets that are enabled. 248a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 249a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Typically, using this search criteria alone is not useful. 250a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * You should also include additional criteria, such as text, 251a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * content-description, or the class name for a widget. 252a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 253a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * If no other search criteria is specified, and there is more 254a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * than one matching widget, the first widget in the tree 255a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * is selected. 256a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 257a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @param val Value to match 258a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @return UiSelector with the specified search criteria 259a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz */ 2604ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz public UiSelector enabled(boolean val) { 261e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return buildSelector(SELECTOR_ENABLED, val); 262e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 263e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 264a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz /** 265a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Set the search criteria to match widgets that have focus. 266a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 267a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Typically, using this search criteria alone is not useful. 268a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * You should also include additional criteria, such as text, 269a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * content-description, or the class name for a widget. 270a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 271a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * If no other search criteria is specified, and there is more 272a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * than one matching widget, the first widget in the tree 273a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * is selected. 274a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 275a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @param val Value to match 276a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @return UiSelector with the specified search criteria 277a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz */ 2784ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz public UiSelector focused(boolean val) { 279e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return buildSelector(SELECTOR_FOCUSED, val); 280e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 281e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 282a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz /** 283a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Set the search criteria to match widgets that are focusable. 284a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 285a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Typically, using this search criteria alone is not useful. 286a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * You should also include additional criteria, such as text, 287a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * content-description, or the class name for a widget. 288a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 289a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * If no other search criteria is specified, and there is more 290a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * than one matching widget, the first widget in the tree 291a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * is selected. 292a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 293a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @param val Value to match 294a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @return UiSelector with the specified search criteria 295a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz */ 2964ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz public UiSelector focusable(boolean val) { 297e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return buildSelector(SELECTOR_FOCUSABLE, val); 298e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 299e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 300a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz /** 301a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Set the search criteria to match widgets that are scrollable. 302a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 303a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Typically, using this search criteria alone is not useful. 304a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * You should also include additional criteria, such as text, 305a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * content-description, or the class name for a widget. 306a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 307a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * If no other search criteria is specified, and there is more 308a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * than one matching widget, the first widget in the tree 309a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * is selected. 310a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 311a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @param val Value to match 312a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @return UiSelector with the specified search criteria 313a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz */ 3144ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz public UiSelector scrollable(boolean val) { 315e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return buildSelector(SELECTOR_SCROLLABLE, val); 316e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 317e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 318a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz /** 319a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Set the search criteria to match widgets that 320a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * are currently selected. 321a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 322a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Typically, using this search criteria alone is not useful. 323a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * You should also include additional criteria, such as text, 324a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * content-description, or the class name for a widget. 325a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 326a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * If no other search criteria is specified, and there is more 327a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * than one matching widget, the first widget in the tree 328a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * is selected. 329a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 330a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @param val Value to match 331a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @return UiSelector with the specified search criteria 332a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz */ 3334ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz public UiSelector selected(boolean val) { 334e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return buildSelector(SELECTOR_SELECTED, val); 335e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 336e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 337a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz /** 338a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Set the search criteria to match widgets that 339a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * are currently checked (usually for checkboxes). 340a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 341a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Typically, using this search criteria alone is not useful. 342a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * You should also include additional criteria, such as text, 343a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * content-description, or the class name for a widget. 344a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 345a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * If no other search criteria is specified, and there is more 346a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * than one matching widget, the first widget in the tree 347a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * is selected. 348a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 349a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @param val Value to match 350a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @return UiSelector with the specified search criteria 351a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz */ 3524ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz public UiSelector checked(boolean val) { 353e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return buildSelector(SELECTOR_CHECKED, val); 354e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 355e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 356a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz /** 357a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Set the search criteria to match widgets that are clickable. 358a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 359a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Typically, using this search criteria alone is not useful. 360a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * You should also include additional criteria, such as text, 361a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * content-description, or the class name for a widget. 362a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 363a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * If no other search criteria is specified, and there is more 364a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * than one matching widget, the first widget in the tree 365a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * is selected. 366a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 367a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @param val Value to match 368a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @return UiSelector with the specified search criteria 369a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz */ 3704ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz public UiSelector clickable(boolean val) { 371e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return buildSelector(SELECTOR_CLICKABLE, val); 372e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 373e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 374a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz /** 375a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Adds a child UiSelector criteria to this selector. 376a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 377a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Use this selector to narrow the search scope to 378a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * child widgets under a specific parent widget. 379a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 380a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @param selector 381a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @return UiSelector with this added search criterion 382a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz */ 3833d50587be8ff021369c90554d814839335b445b0Adam Momtaz public UiSelector childSelector(UiSelector selector) { 3843d50587be8ff021369c90554d814839335b445b0Adam Momtaz return buildSelector(SELECTOR_CHILD, selector); 385e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 386e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 3873d50587be8ff021369c90554d814839335b445b0Adam Momtaz private UiSelector patternSelector(UiSelector selector) { 3883d50587be8ff021369c90554d814839335b445b0Adam Momtaz return buildSelector(SELECTOR_PATTERN, selector); 389e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 390e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 3913d50587be8ff021369c90554d814839335b445b0Adam Momtaz private UiSelector containerSelector(UiSelector selector) { 3923d50587be8ff021369c90554d814839335b445b0Adam Momtaz return buildSelector(SELECTOR_CONTAINER, selector); 393e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 394e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 395a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz /** 396a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Adds a child UiSelector criteria to this selector which is used to 397a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * start search from the parent widget. 398a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 399a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Use this selector to narrow the search scope to 400a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * sibling widgets as well all child widgets under a parent. 401a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 402a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @param selector 403a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @return UiSelector with this added search criterion 404a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz */ 4053d50587be8ff021369c90554d814839335b445b0Adam Momtaz public UiSelector fromParent(UiSelector selector) { 4063d50587be8ff021369c90554d814839335b445b0Adam Momtaz return buildSelector(SELECTOR_PARENT, selector); 407e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 408e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 409a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz /** 410a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * Set the search criteria to match the package name 411a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * of the application that contains the widget. 412a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 413a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @param name Value to match 414a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * @return UiSelector with the specified search criteria 415a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz */ 4164ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz public UiSelector packageName(String name) { 417e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return buildSelector(SELECTOR_PACKAGE_NAME, name); 418e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 419e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 420e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu /** 4213d50587be8ff021369c90554d814839335b445b0Adam Momtaz * Building a UiSelector always returns a new UiSelector and never modifies the 4223d50587be8ff021369c90554d814839335b445b0Adam Momtaz * existing UiSelector being used. 423e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu */ 4244ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz private UiSelector buildSelector(int selectorId, Object selectorValue) { 4253d50587be8ff021369c90554d814839335b445b0Adam Momtaz UiSelector selector = new UiSelector(this); 426e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if(selectorId == SELECTOR_CHILD || selectorId == SELECTOR_PARENT) 4273d50587be8ff021369c90554d814839335b445b0Adam Momtaz selector.getLastSubSelector().mSelectorAttributes.put(selectorId, selectorValue); 428e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu else 4293d50587be8ff021369c90554d814839335b445b0Adam Momtaz selector.mSelectorAttributes.put(selectorId, selectorValue); 4303d50587be8ff021369c90554d814839335b445b0Adam Momtaz return selector; 431e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 432e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 433e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu /** 434e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * Selectors may have a hierarchy defined by specifying child nodes to be matched. 435e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * It is not necessary that every selector have more than one level. A selector 436e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * can also be a single level referencing only one node. In such cases the return 437e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * it null. 438a46ac3504426564954292b13380120e8cc6b1527Adam Momtaz * 439e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * @return a child selector if one exists. Else null if this selector does not 440e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * reference child node. 441e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu */ 4424ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz UiSelector getChildSelector() { 4433d50587be8ff021369c90554d814839335b445b0Adam Momtaz UiSelector selector = (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_CHILD, null); 4443d50587be8ff021369c90554d814839335b445b0Adam Momtaz if(selector != null) 4453d50587be8ff021369c90554d814839335b445b0Adam Momtaz return new UiSelector(selector); 446e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return null; 447e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 448e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 4494ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz UiSelector getPatternSelector() { 4503d50587be8ff021369c90554d814839335b445b0Adam Momtaz UiSelector selector = 4513d50587be8ff021369c90554d814839335b445b0Adam Momtaz (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_PATTERN, null); 4523d50587be8ff021369c90554d814839335b445b0Adam Momtaz if(selector != null) 4533d50587be8ff021369c90554d814839335b445b0Adam Momtaz return new UiSelector(selector); 454e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return null; 455e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 456e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 4574ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz UiSelector getContainerSelector() { 4583d50587be8ff021369c90554d814839335b445b0Adam Momtaz UiSelector selector = 4593d50587be8ff021369c90554d814839335b445b0Adam Momtaz (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_CONTAINER, null); 4603d50587be8ff021369c90554d814839335b445b0Adam Momtaz if(selector != null) 4613d50587be8ff021369c90554d814839335b445b0Adam Momtaz return new UiSelector(selector); 462e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return null; 463e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 464e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 4654ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz UiSelector getParentSelector() { 4663d50587be8ff021369c90554d814839335b445b0Adam Momtaz UiSelector selector = 4673d50587be8ff021369c90554d814839335b445b0Adam Momtaz (UiSelector) mSelectorAttributes.get(UiSelector.SELECTOR_PARENT, null); 4683d50587be8ff021369c90554d814839335b445b0Adam Momtaz if(selector != null) 4693d50587be8ff021369c90554d814839335b445b0Adam Momtaz return new UiSelector(selector); 470e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return null; 471e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 472e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 473e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu int getInstance() { 4744ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz return getInt(UiSelector.SELECTOR_INSTANCE); 475e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 476e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 477e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu String getString(int criterion) { 478e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return (String) mSelectorAttributes.get(criterion, null); 479e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 480e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 481e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu boolean getBoolean(int criterion) { 482e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return (Boolean) mSelectorAttributes.get(criterion, false); 483e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 484e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 485e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu int getInt(int criterion) { 486e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return (Integer) mSelectorAttributes.get(criterion, 0); 487e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 488e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 489e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu boolean isMatchFor(AccessibilityNodeInfo node, int index) { 490e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu int size = mSelectorAttributes.size(); 491e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu for(int x = 0; x < size; x++) { 492e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu CharSequence s = null; 493e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu int criterion = mSelectorAttributes.keyAt(x); 494e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu switch(criterion) { 4954ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz case UiSelector.SELECTOR_INDEX: 496e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if(index != this.getInt(criterion)) 497e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 498e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 4994ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz case UiSelector.SELECTOR_CHECKED: 500e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if (node.isChecked() != getBoolean(criterion)) { 501e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 502e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 503e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 5044ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz case UiSelector.SELECTOR_CLASS: 505e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu s = node.getClassName(); 506e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if (s == null || !s.toString().contentEquals(getString(criterion))) { 507e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 508e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 509e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 5104ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz case UiSelector.SELECTOR_CLICKABLE: 511e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if (node.isClickable() != getBoolean(criterion)) { 512e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 513e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 514e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 5154ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz case UiSelector.SELECTOR_CONTAINS_DESCRIPTION: 516e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu s = node.getContentDescription(); 517e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if(s == null || !s.toString().toLowerCase() 518e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu .contains(getString(criterion).toLowerCase())) { 519e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 520e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 521e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 5224ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz case UiSelector.SELECTOR_START_DESCRIPTION: 523e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu s = node.getContentDescription(); 524e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if(s == null || !s.toString().toLowerCase() 525e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu .startsWith(getString(criterion).toLowerCase())) { 526e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 527e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 528e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 5294ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz case UiSelector.SELECTOR_DESCRIPTION: 530e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu s = node.getContentDescription(); 531e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if(s == null || !s.toString().contentEquals(getString(criterion))) { 532e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 533e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 534e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 5354ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz case UiSelector.SELECTOR_CONTAINS_TEXT: 536e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu s = node.getText(); 537e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if(s == null || !s.toString().toLowerCase() 538e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu .contains(getString(criterion).toLowerCase())) { 539e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 540e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 541e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 5424ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz case UiSelector.SELECTOR_START_TEXT: 543e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu s = node.getText(); 544e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if(s == null || !s.toString().toLowerCase() 545e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu .startsWith(getString(criterion).toLowerCase())) { 546e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 547e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 548e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 5494ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz case UiSelector.SELECTOR_TEXT: 550e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu s = node.getText(); 551e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if(s == null || !s.toString().contentEquals(getString(criterion))) { 552e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 553e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 554e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 5554ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz case UiSelector.SELECTOR_ENABLED: 556e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if(node.isEnabled() != getBoolean(criterion)) { 557e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 558e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 559e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 5604ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz case UiSelector.SELECTOR_FOCUSABLE: 561e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if(node.isFocusable() != getBoolean(criterion)) { 562e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 563e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 564e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 5654ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz case UiSelector.SELECTOR_FOCUSED: 566e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if(node.isFocused() != getBoolean(criterion)) { 567e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 568e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 569e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 5704ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz case UiSelector.SELECTOR_ID: 571e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; //TODO: do we need this for AccessibilityNodeInfo.id? 5724ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz case UiSelector.SELECTOR_PACKAGE_NAME: 573e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu s = node.getPackageName(); 574e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if(s == null || !s.toString().contentEquals(getString(criterion))) { 575e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 576e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 577e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 5784ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz case UiSelector.SELECTOR_SCROLLABLE: 579e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if(node.isScrollable() != getBoolean(criterion)) { 580e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 581e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 582e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 5834ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz case UiSelector.SELECTOR_SELECTED: 584e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if(node.isSelected() != getBoolean(criterion)) { 585e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 586e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 587e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 588e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 589e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 590e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return matchOrUpdateInstance(); 591e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 592e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 593e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu private boolean matchOrUpdateInstance() { 594e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu int currentSelectorCounter = 0; 595e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu int currentSelectorInstance = 0; 596e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 597e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // matched attributes - now check for matching instance number 5984ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz if(mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_INSTANCE) > 0) { 5994ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz currentSelectorInstance = 6004ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz (Integer)mSelectorAttributes.get(UiSelector.SELECTOR_INSTANCE); 601e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 602e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 603e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // instance is required. Add count if not already counting 6044ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz if(mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_COUNT) > 0) { 6054ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz currentSelectorCounter = (Integer)mSelectorAttributes.get(UiSelector.SELECTOR_COUNT); 606e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 607e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 608e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // Verify 609e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if (currentSelectorInstance == currentSelectorCounter) { 610e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return true; 611e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 612e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu // Update count 613e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if (currentSelectorInstance > currentSelectorCounter) { 6144ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz mSelectorAttributes.put(UiSelector.SELECTOR_COUNT, ++currentSelectorCounter); 615e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 616e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 617e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 618e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 619e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu /** 620e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * Leaf selector indicates no more child or parent selectors 621e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * are declared in the this selector. 622e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * @return true if is leaf. 623e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu */ 624e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu boolean isLeaf() { 6254ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz if(mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_CHILD) < 0 && 6264ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_PARENT) < 0) { 627e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return true; 628e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 629e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 630e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 631e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 632e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu boolean hasChildSelector() { 6334ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz if(mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_CHILD) < 0) { 634e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 635e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 636e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return true; 637e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 638e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 639e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu boolean hasPatternSelector() { 6404ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz if(mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_PATTERN) < 0) { 641e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 642e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 643e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return true; 644e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 645e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 646e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu boolean hasContainerSelector() { 6474ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz if(mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_CONTAINER) < 0) { 648e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 649e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 650e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return true; 651e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 652e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 653e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu boolean hasParentSelector() { 6544ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz if(mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_PARENT) < 0) { 655e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return false; 656e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 657e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return true; 658e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 659e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 660e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu /** 661e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * Returns the deepest selector in the chain of possible sub selectors. 6624ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz * A chain of selector is created when either of {@link UiSelector#childSelector(UiSelector)} 6634ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz * or {@link UiSelector#fromParent(UiSelector)} are used once or more in the construction of 664e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu * a selector. 6653d50587be8ff021369c90554d814839335b445b0Adam Momtaz * @return last UiSelector in chain 666e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu */ 6674ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz private UiSelector getLastSubSelector() { 6684ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz if(mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_CHILD) >= 0) { 6694ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz UiSelector child = (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_CHILD); 670e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if(child.getLastSubSelector() == null) { 671e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return child; 672e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 673e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return child.getLastSubSelector(); 6744ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz } else if(mSelectorAttributes.indexOfKey(UiSelector.SELECTOR_PARENT) >= 0) { 6754ab790eccf6d5c27f542056b87d26d38f7caeeb3Adam Momtaz UiSelector parent = (UiSelector)mSelectorAttributes.get(UiSelector.SELECTOR_PARENT); 676e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if(parent.getLastSubSelector() == null) { 677e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return parent; 678e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 679e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return parent.getLastSubSelector(); 680e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 681e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return this; 682e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 683e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 684e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu @Override 685e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu public String toString() { 686e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return dumpToString(true); 687e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 688e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu 689e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu String dumpToString(boolean all) { 690e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu StringBuilder builder = new StringBuilder(); 6913d50587be8ff021369c90554d814839335b445b0Adam Momtaz builder.append(UiSelector.class.getSimpleName() + "["); 692e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu final int criterionCount = mSelectorAttributes.size(); 693e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu for (int i = 0; i < criterionCount; i++) { 694e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if (i > 0) { 695e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append(", "); 696e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 697e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu final int criterion = mSelectorAttributes.keyAt(i); 698e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu switch (criterion) { 699e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_TEXT: 700e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("TEXT=").append(mSelectorAttributes.valueAt(i)); 701e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 702e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_START_TEXT: 703e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("START_TEXT=").append(mSelectorAttributes.valueAt(i)); 704e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 705e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_CONTAINS_TEXT: 706e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("CONTAINS_TEXT=").append(mSelectorAttributes.valueAt(i)); 707e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 708e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_CLASS: 709e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("CLASS=").append(mSelectorAttributes.valueAt(i)); 710e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 711e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_DESCRIPTION: 712e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("DESCRIPTION=").append(mSelectorAttributes.valueAt(i)); 713e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 714e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_START_DESCRIPTION: 715e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("START_DESCRIPTION=").append(mSelectorAttributes.valueAt(i)); 716e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 717e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_CONTAINS_DESCRIPTION: 718e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("CONTAINS_DESCRIPTION=").append(mSelectorAttributes.valueAt(i)); 719e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 720e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_INDEX: 721e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("INDEX=").append(mSelectorAttributes.valueAt(i)); 722e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 723e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_INSTANCE: 724e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("INSTANCE=").append(mSelectorAttributes.valueAt(i)); 725e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 726e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_ENABLED: 727e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("ENABLED=").append(mSelectorAttributes.valueAt(i)); 728e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 729e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_FOCUSED: 730e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("FOCUSED=").append(mSelectorAttributes.valueAt(i)); 731e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 732e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_FOCUSABLE: 733e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("FOCUSABLE=").append(mSelectorAttributes.valueAt(i)); 734e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 735e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_SCROLLABLE: 736e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("SCROLLABLE=").append(mSelectorAttributes.valueAt(i)); 737e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 738e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_CLICKABLE: 739e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("CLICKABLE=").append(mSelectorAttributes.valueAt(i)); 740e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 741e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_CHECKED: 742e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("CHECKED=").append(mSelectorAttributes.valueAt(i)); 743e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 744e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_SELECTED: 745e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("SELECTED=").append(mSelectorAttributes.valueAt(i)); 746e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 747e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_ID: 748e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("ID=").append(mSelectorAttributes.valueAt(i)); 749e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 750e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_CHILD: 751e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if(all) 752e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("CHILD=").append(mSelectorAttributes.valueAt(i)); 753e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu else 754e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("CHILD[..]"); 755e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 756e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_PATTERN: 757e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if(all) 758e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("PATTERN=").append(mSelectorAttributes.valueAt(i)); 759e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu else 760e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("PATTERN[..]"); 761e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 762e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_CONTAINER: 763e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if(all) 764e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("CONTAINER=").append(mSelectorAttributes.valueAt(i)); 765e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu else 766e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("CONTAINER[..]"); 767e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 768e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_PARENT: 769e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu if(all) 770e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("PARENT=").append(mSelectorAttributes.valueAt(i)); 771e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu else 772e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("PARENT[..]"); 773e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 774e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_COUNT: 775e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("COUNT=").append(mSelectorAttributes.valueAt(i)); 776e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 777e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu case SELECTOR_PACKAGE_NAME: 778e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("PACKAGE NAME=").append(mSelectorAttributes.valueAt(i)); 779e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu break; 780e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu default: 781e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("UNDEFINED="+criterion+" ").append(mSelectorAttributes.valueAt(i)); 782e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 783e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 784e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu builder.append("]"); 785e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu return builder.toString(); 786e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu } 787e54d649fb83a0a44516e5c25a9ac1992c8950e59Guang Zhu} 788