Home | History | Annotate | Download | only in droiddriver
      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. */
     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    */
     74   void setText(String text);
     75 
     76   /** Gets the content description of this element. */
     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    */
     85   String getClassName();
     86 
     87   /** Gets the resource id of this element. */
     88   String getResourceId();
     89 
     90   /** Gets the package name of this element. */
     91   String getPackageName();
     92 
     93   /** @return whether or not this element is visible on the device's display. */
     94   boolean isVisible();
     95 
     96   /** @return whether this element is checkable. */
     97   boolean isCheckable();
     98 
     99   /** @return whether this element is checked. */
    100   boolean isChecked();
    101 
    102   /** @return whether this element is clickable. */
    103   boolean isClickable();
    104 
    105   /** @return whether this element is enabled. */
    106   boolean isEnabled();
    107 
    108   /** @return whether this element is focusable. */
    109   boolean isFocusable();
    110 
    111   /** @return whether this element is focused. */
    112   boolean isFocused();
    113 
    114   /** @return whether this element is scrollable. */
    115   boolean isScrollable();
    116 
    117   /** @return whether this element is long-clickable. */
    118   boolean isLongClickable();
    119 
    120   /** @return whether this element is password. */
    121   boolean isPassword();
    122 
    123   /** @return whether this element is selected. */
    124   boolean isSelected();
    125 
    126   /**
    127    * Gets the UiElement bounds in screen coordinates. The coordinates may not be visible on screen.
    128    */
    129   Rect getBounds();
    130 
    131   /** Gets the UiElement bounds in screen coordinates. The coordinates will be visible on screen. */
    132   Rect getVisibleBounds();
    133 
    134   /** @return value of the given attribute. */
    135   @SuppressWarnings("TypeParameterUnusedInFormals")
    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    */
    144   boolean perform(Action action);
    145 
    146   /** Clicks this element. The click will be at the center of the visible element. */
    147   void click();
    148 
    149   /** Long-clicks this element. The click will be at the center of the visible element. */
    150   void longClick();
    151 
    152   /** Double-clicks this element. The click will be at the center of the visible element. */
    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    */
    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    */
    179   List<? extends UiElement> getChildren(Predicate<? super UiElement> predicate);
    180 
    181   /** Gets the parent. */
    182   UiElement getParent();
    183 
    184   /** Gets the {@link InputInjector} for injecting InputEvent. */
    185   InputInjector getInjector();
    186 }
    187