1 /* 2 * Copyright (C) 2013 DroidDriver committers 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package io.appium.droiddriver; 18 19 import android.graphics.Rect; 20 import android.view.accessibility.AccessibilityNodeInfo; 21 import io.appium.droiddriver.actions.Action; 22 import io.appium.droiddriver.actions.InputInjector; 23 import io.appium.droiddriver.finders.Attribute; 24 import io.appium.droiddriver.finders.Predicate; 25 import io.appium.droiddriver.instrumentation.InstrumentationDriver; 26 import io.appium.droiddriver.scroll.Direction.PhysicalDirection; 27 import io.appium.droiddriver.uiautomation.UiAutomationDriver; 28 import java.util.List; 29 30 /** 31 * Represents an UI element within an Android App. 32 * 33 * <p>UI elements are generally views. Users can get attributes and perform actions. Note that 34 * actions often update UiElement, so users are advised not to store instances for later use -- the 35 * instances could become stale. 36 */ 37 public interface UiElement { 38 /** Filters out invisible children. */ 39 Predicate<UiElement> VISIBLE = 40 new Predicate<UiElement>() { 41 @Override 42 public boolean apply(UiElement element) { 43 return element.isVisible(); 44 } 45 46 @Override 47 public String toString() { 48 return "VISIBLE"; 49 } 50 }; 51 52 /** Gets the text of this element. */ getText()53 String getText(); 54 55 /** 56 * Sets the text of this element. The implementation may not work on all UiElements if the 57 * underlying view is not EditText. 58 * 59 * <p>If this element already has text, it is cleared first if the device has API 11 or higher. 60 * 61 * <p>TODO: Support this behavior on older devices. 62 * 63 * <p>The soft keyboard may be shown after this call. If the {@code text} ends with {@code '\n'}, 64 * the IME may be closed automatically. If the soft keyboard is open, you can call {@link 65 * UiDevice#pressBack()} to close it. 66 * 67 * <p>If you are using {@link io.appium.droiddriver.instrumentation.InstrumentationDriver}, you 68 * may use {@link io.appium.droiddriver.actions.view.CloseKeyboardAction} to close it. The 69 * advantage of {@code CloseKeyboardAction} is that it is a no-op if the soft keyboard is hidden. 70 * This is useful when the state of the soft keyboard cannot be determined. 71 * 72 * @param text the text to enter 73 */ setText(String text)74 void setText(String text); 75 76 /** Gets the content description of this element. */ getContentDescription()77 String getContentDescription(); 78 79 /** 80 * Gets the class name of the underlying view. The actual name could be overridden if viewed with 81 * uiautomatorviewer, which gets the name from {@link AccessibilityNodeInfo#getClassName}. If the 82 * app uses custom View classes that do not call {@link AccessibilityNodeInfo#setClassName} with 83 * the actual class name, uiautomatorviewer will report the wrong name. 84 */ getClassName()85 String getClassName(); 86 87 /** Gets the resource id of this element. */ getResourceId()88 String getResourceId(); 89 90 /** Gets the package name of this element. */ getPackageName()91 String getPackageName(); 92 93 /** @return whether or not this element is visible on the device's display. */ isVisible()94 boolean isVisible(); 95 96 /** @return whether this element is checkable. */ isCheckable()97 boolean isCheckable(); 98 99 /** @return whether this element is checked. */ isChecked()100 boolean isChecked(); 101 102 /** @return whether this element is clickable. */ isClickable()103 boolean isClickable(); 104 105 /** @return whether this element is enabled. */ isEnabled()106 boolean isEnabled(); 107 108 /** @return whether this element is focusable. */ isFocusable()109 boolean isFocusable(); 110 111 /** @return whether this element is focused. */ isFocused()112 boolean isFocused(); 113 114 /** @return whether this element is scrollable. */ isScrollable()115 boolean isScrollable(); 116 117 /** @return whether this element is long-clickable. */ isLongClickable()118 boolean isLongClickable(); 119 120 /** @return whether this element is password. */ isPassword()121 boolean isPassword(); 122 123 /** @return whether this element is selected. */ isSelected()124 boolean isSelected(); 125 126 /** 127 * Gets the UiElement bounds in screen coordinates. The coordinates may not be visible on screen. 128 */ getBounds()129 Rect getBounds(); 130 131 /** Gets the UiElement bounds in screen coordinates. The coordinates will be visible on screen. */ getVisibleBounds()132 Rect getVisibleBounds(); 133 134 /** @return value of the given attribute. */ 135 @SuppressWarnings("TypeParameterUnusedInFormals") get(Attribute attribute)136 <T> T get(Attribute attribute); 137 138 /** 139 * Executes the given action. 140 * 141 * @param action the action to execute 142 * @return true if the action is successful 143 */ perform(Action action)144 boolean perform(Action action); 145 146 /** Clicks this element. The click will be at the center of the visible element. */ click()147 void click(); 148 149 /** Long-clicks this element. The click will be at the center of the visible element. */ longClick()150 void longClick(); 151 152 /** Double-clicks this element. The click will be at the center of the visible element. */ doubleClick()153 void doubleClick(); 154 155 /** 156 * Scrolls in the given direction. 157 * 158 * @param direction specifies where the view port will move instead of the finger 159 */ scroll(PhysicalDirection direction)160 void scroll(PhysicalDirection direction); 161 162 /** 163 * Gets an immutable {@link List} of immediate children that satisfy {@code predicate}. It always 164 * filters children that are null. This gives a low level access to the underlying data. Do not 165 * use it unless you are sure about the subtle details. Note the count may not be what you expect. 166 * For instance, a dynamic list may show more items when scrolling beyond the end, varying the 167 * count. The count also depends on the driver implementation: 168 * 169 * <ul> 170 * <li>{@link InstrumentationDriver} includes all. 171 * <li>the Accessibility API (which {@link UiAutomationDriver} depends on) does not include 172 * off-screen children, but may include invisible on-screen children. 173 * </ul> 174 * 175 * <p>Another discrepancy between {@link InstrumentationDriver} {@link UiAutomationDriver} is the 176 * order of children. The Accessibility API returns children in the order of layout (see {@link 177 * android.view.ViewGroup#addChildrenForAccessibility}, which is added in API16). 178 */ getChildren(Predicate<? super UiElement> predicate)179 List<? extends UiElement> getChildren(Predicate<? super UiElement> predicate); 180 181 /** Gets the parent. */ getParent()182 UiElement getParent(); 183 184 /** Gets the {@link InputInjector} for injecting InputEvent. */ getInjector()185 InputInjector getInjector(); 186 } 187