157e46577852ffa1dde4662f6018f7fbcfacb6148Thanh Le/*
21194ec356a16f3c6dcf408289e36e42c149d6dc8Kevin Jin * Copyright (C) 2013 DroidDriver committers
357e46577852ffa1dde4662f6018f7fbcfacb6148Thanh Le *
457e46577852ffa1dde4662f6018f7fbcfacb6148Thanh Le * Licensed under the Apache License, Version 2.0 (the "License");
557e46577852ffa1dde4662f6018f7fbcfacb6148Thanh Le * you may not use this file except in compliance with the License.
657e46577852ffa1dde4662f6018f7fbcfacb6148Thanh Le * You may obtain a copy of the License at
757e46577852ffa1dde4662f6018f7fbcfacb6148Thanh Le *
857e46577852ffa1dde4662f6018f7fbcfacb6148Thanh Le *      http://www.apache.org/licenses/LICENSE-2.0
957e46577852ffa1dde4662f6018f7fbcfacb6148Thanh Le *
1057e46577852ffa1dde4662f6018f7fbcfacb6148Thanh Le * Unless required by applicable law or agreed to in writing, software
1157e46577852ffa1dde4662f6018f7fbcfacb6148Thanh Le * distributed under the License is distributed on an "AS IS" BASIS,
1257e46577852ffa1dde4662f6018f7fbcfacb6148Thanh Le * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1357e46577852ffa1dde4662f6018f7fbcfacb6148Thanh Le * See the License for the specific language governing permissions and
1457e46577852ffa1dde4662f6018f7fbcfacb6148Thanh Le * limitations under the License.
1557e46577852ffa1dde4662f6018f7fbcfacb6148Thanh Le */
1657e46577852ffa1dde4662f6018f7fbcfacb6148Thanh Le
171194ec356a16f3c6dcf408289e36e42c149d6dc8Kevin Jinpackage com.google.android.droiddriver;
1857e46577852ffa1dde4662f6018f7fbcfacb6148Thanh Le
19a6c69788f9ff3360c02b9362bb65c136fe0b9a99Kevin Jinimport android.graphics.Rect;
20a6c69788f9ff3360c02b9362bb65c136fe0b9a99Kevin Jin
211194ec356a16f3c6dcf408289e36e42c149d6dc8Kevin Jinimport com.google.android.droiddriver.actions.Action;
2274676fdd3c8a9e599eddd13bea56898674d9916aKevin Jinimport com.google.android.droiddriver.actions.InputInjector;
237576fbbba2bf515908b45293b7156b5bfe088938Kevin Jinimport com.google.android.droiddriver.finders.Attribute;
2417342a5115d7575d44a99fed9c7032e3ab316dccKevin Jinimport com.google.android.droiddriver.finders.Predicate;
25f9c6c5063b38b623679e47d7095cccddb0481319Kevin Jinimport com.google.android.droiddriver.instrumentation.InstrumentationDriver;
2629d66eeee5d30f7db747cceeb84defec961b4125Kevin Jinimport com.google.android.droiddriver.scroll.Direction.PhysicalDirection;
27f9c6c5063b38b623679e47d7095cccddb0481319Kevin Jinimport com.google.android.droiddriver.uiautomation.UiAutomationDriver;
28f9c6c5063b38b623679e47d7095cccddb0481319Kevin Jin
29f9c6c5063b38b623679e47d7095cccddb0481319Kevin Jinimport java.util.List;
308e610ed585685c55e2cfd010b4233eafc7d568c2Thanh Le
3157e46577852ffa1dde4662f6018f7fbcfacb6148Thanh Le/**
3257e46577852ffa1dde4662f6018f7fbcfacb6148Thanh Le * Represents an UI element within an Android App.
33646e91a139ecd447d23c7d604aed96ee306ce7edKevin Jin * <p>
34f9c6c5063b38b623679e47d7095cccddb0481319Kevin Jin * UI elements are generally views. Users can get attributes and perform
35f9c6c5063b38b623679e47d7095cccddb0481319Kevin Jin * actions. Note that actions often update UiElement, so users are advised not
36f9c6c5063b38b623679e47d7095cccddb0481319Kevin Jin * to store instances for later use -- the instances could become stale.
3757e46577852ffa1dde4662f6018f7fbcfacb6148Thanh Le */
38646e91a139ecd447d23c7d604aed96ee306ce7edKevin Jinpublic interface UiElement {
39646e91a139ecd447d23c7d604aed96ee306ce7edKevin Jin  /**
40a793befd4eb754943dd93aa7178606f1c6170824Thanh Le   * Gets the text of this element.
4157e46577852ffa1dde4662f6018f7fbcfacb6148Thanh Le   */
4257e46577852ffa1dde4662f6018f7fbcfacb6148Thanh Le  String getText();
4357e46577852ffa1dde4662f6018f7fbcfacb6148Thanh Le
4457e46577852ffa1dde4662f6018f7fbcfacb6148Thanh Le  /**
45a793befd4eb754943dd93aa7178606f1c6170824Thanh Le   * Gets the content description of this element.
46a793befd4eb754943dd93aa7178606f1c6170824Thanh Le   */
47a793befd4eb754943dd93aa7178606f1c6170824Thanh Le  String getContentDescription();
48a793befd4eb754943dd93aa7178606f1c6170824Thanh Le
49a793befd4eb754943dd93aa7178606f1c6170824Thanh Le  /**
509f81086b618594cb080adf33548edd0c999e388eKevin Jin   * Gets the class name of the underlying view. The actual name could be
519f81086b618594cb080adf33548edd0c999e388eKevin Jin   * overridden.
529f81086b618594cb080adf33548edd0c999e388eKevin Jin   *
539f81086b618594cb080adf33548edd0c999e388eKevin Jin   * @see com.google.android.droiddriver.instrumentation.ViewElement#overrideClassName
54544e68a6af3ef73316b9994bb7a63790c19415b9Thanh Le   */
55544e68a6af3ef73316b9994bb7a63790c19415b9Thanh Le  String getClassName();
56544e68a6af3ef73316b9994bb7a63790c19415b9Thanh Le
57544e68a6af3ef73316b9994bb7a63790c19415b9Thanh Le  /**
5807704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin   * Gets the resource id of this element.
598e610ed585685c55e2cfd010b4233eafc7d568c2Thanh Le   */
6007704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin  String getResourceId();
618e610ed585685c55e2cfd010b4233eafc7d568c2Thanh Le
628e610ed585685c55e2cfd010b4233eafc7d568c2Thanh Le  /**
6307704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin   * Gets the package name of this element.
6457e46577852ffa1dde4662f6018f7fbcfacb6148Thanh Le   */
6507704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin  String getPackageName();
6631692a4134ef82a4144d25980c0c5f14bbf1bfadThanh Le
6731692a4134ef82a4144d25980c0c5f14bbf1bfadThanh Le  /**
6807704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin   * @return whether or not this element is visible on the device's display.
6931692a4134ef82a4144d25980c0c5f14bbf1bfadThanh Le   */
7031692a4134ef82a4144d25980c0c5f14bbf1bfadThanh Le  boolean isVisible();
71544e68a6af3ef73316b9994bb7a63790c19415b9Thanh Le
72544e68a6af3ef73316b9994bb7a63790c19415b9Thanh Le  /**
7307704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin   * @return whether this element is checkable.
7407704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin   */
7507704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin  boolean isCheckable();
7607704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin
7707704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin  /**
7807704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin   * @return whether this element is checked.
7907704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin   */
8007704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin  boolean isChecked();
8107704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin
8207704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin  /**
8307704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin   * @return whether this element is clickable.
8407704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin   */
8507704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin  boolean isClickable();
8607704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin
8707704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin  /**
8807704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin   * @return whether this element is enabled.
8907704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin   */
9007704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin  boolean isEnabled();
9107704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin
9207704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin  /**
9307704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin   * @return whether this element is focusable.
9407704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin   */
9507704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin  boolean isFocusable();
9607704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin
9707704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin  /**
9807704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin   * @return whether this element is focused.
9907704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin   */
10007704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin  boolean isFocused();
10107704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin
10207704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin  /**
10307704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin   * @return whether this element is scrollable.
10407704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin   */
10507704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin  boolean isScrollable();
10607704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin
10707704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin  /**
10807704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin   * @return whether this element is long-clickable.
10907704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin   */
11007704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin  boolean isLongClickable();
11107704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin
11207704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin  /**
11307704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin   * @return whether this element is password.
11407704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin   */
11507704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin  boolean isPassword();
11607704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin
11707704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin  /**
11807704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin   * @return whether this element is selected.
11907704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin   */
12007704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin  boolean isSelected();
12107704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin
12207704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin  /**
123646e91a139ecd447d23c7d604aed96ee306ce7edKevin Jin   * Gets the UiElement bounds in screen coordinates. The coordinates may not be
124646e91a139ecd447d23c7d604aed96ee306ce7edKevin Jin   * visible on screen.
1258e610ed585685c55e2cfd010b4233eafc7d568c2Thanh Le   */
1260858f7292b7e7f32c25662d853c9d8ed8db1403fKevin Jin  Rect getBounds();
1278e610ed585685c55e2cfd010b4233eafc7d568c2Thanh Le
1288e610ed585685c55e2cfd010b4233eafc7d568c2Thanh Le  /**
1299f81086b618594cb080adf33548edd0c999e388eKevin Jin   * Gets the UiElement bounds in screen coordinates. The coordinates will be
1309f81086b618594cb080adf33548edd0c999e388eKevin Jin   * visible on screen.
1317dde4b200c490587409e0301e58261210e7a5896Tony Wickham   */
1327dde4b200c490587409e0301e58261210e7a5896Tony Wickham  Rect getVisibleBounds();
1337dde4b200c490587409e0301e58261210e7a5896Tony Wickham
1347dde4b200c490587409e0301e58261210e7a5896Tony Wickham  /**
1352acc13e041cb065f90ab7882e095f05cb275dc68Kevin Jin   * @return value of the given attribute.
1362acc13e041cb065f90ab7882e095f05cb275dc68Kevin Jin   */
1372acc13e041cb065f90ab7882e095f05cb275dc68Kevin Jin  <T> T get(Attribute attribute);
1382acc13e041cb065f90ab7882e095f05cb275dc68Kevin Jin
1392acc13e041cb065f90ab7882e095f05cb275dc68Kevin Jin  /**
14007704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin   * Executes the given action.
14107704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin   *
14207704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin   * @param action The action to execute
14307704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin   * @return true if the action is successful
14407704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin   */
14507704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin  boolean perform(Action action);
14607704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin
14707704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin  /**
14807704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin   * Sets the text of this element.
14907704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin   *
15007704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin   * @param text The text to enter.
15107704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin   */
15207704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin  void setText(String text);
15307704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin
15407704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin  /**
15507704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin   * Clicks this element. The click will be at the center of the visible
15607704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin   * element.
15707704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin   */
15807704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin  void click();
15907704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin
16007704975f91b729d9be3a13d6a2d3dfdbbd7d426Kevin Jin  /**
161f9c2a591497874769b87bf492a0666cf853e0ae5Kevin Jin   * Long-clicks this element. The click will be at the center of the visible
162f9c2a591497874769b87bf492a0666cf853e0ae5Kevin Jin   * element.
163f9c2a591497874769b87bf492a0666cf853e0ae5Kevin Jin   */
164f9c2a591497874769b87bf492a0666cf853e0ae5Kevin Jin  void longClick();
165f9c2a591497874769b87bf492a0666cf853e0ae5Kevin Jin
166f9c2a591497874769b87bf492a0666cf853e0ae5Kevin Jin  /**
167f9c2a591497874769b87bf492a0666cf853e0ae5Kevin Jin   * Double-clicks this element. The click will be at the center of the visible
168f9c2a591497874769b87bf492a0666cf853e0ae5Kevin Jin   * element.
169f9c2a591497874769b87bf492a0666cf853e0ae5Kevin Jin   */
170f9c2a591497874769b87bf492a0666cf853e0ae5Kevin Jin  void doubleClick();
171f9c2a591497874769b87bf492a0666cf853e0ae5Kevin Jin
172f9c2a591497874769b87bf492a0666cf853e0ae5Kevin Jin  /**
173a738fe74f57f48dde2dd7a28479bab3f5441dadbKevin Jin   * Scrolls in the given direction.
174a738fe74f57f48dde2dd7a28479bab3f5441dadbKevin Jin   *
175a738fe74f57f48dde2dd7a28479bab3f5441dadbKevin Jin   * @param direction specifies where the view port will move, instead of the
176a738fe74f57f48dde2dd7a28479bab3f5441dadbKevin Jin   *        finger.
177544e68a6af3ef73316b9994bb7a63790c19415b9Thanh Le   */
17829d66eeee5d30f7db747cceeb84defec961b4125Kevin Jin  void scroll(PhysicalDirection direction);
1790d7b67b43f83536708a6ae0330e739744049a48eKevin Jin
1800d7b67b43f83536708a6ae0330e739744049a48eKevin Jin  /**
181f9c6c5063b38b623679e47d7095cccddb0481319Kevin Jin   * Gets an immutable {@link List} of immediate children that satisfy
1826f160bb942de53103e4f4ed54acaafe2da629fcfKevin Jin   * {@code predicate}. It always filters children that are null. This gives a
1836f160bb942de53103e4f4ed54acaafe2da629fcfKevin Jin   * low level access to the underlying data. Do not use it unless you are sure
1846f160bb942de53103e4f4ed54acaafe2da629fcfKevin Jin   * about the subtle details. Note the count may not be what you expect. For
1856f160bb942de53103e4f4ed54acaafe2da629fcfKevin Jin   * instance, a dynamic list may show more items when scrolling beyond the end,
1866f160bb942de53103e4f4ed54acaafe2da629fcfKevin Jin   * varying the count. The count also depends on the driver implementation:
1876f160bb942de53103e4f4ed54acaafe2da629fcfKevin Jin   * <ul>
1886f160bb942de53103e4f4ed54acaafe2da629fcfKevin Jin   * <li>{@link InstrumentationDriver} includes all.</li>
1896f160bb942de53103e4f4ed54acaafe2da629fcfKevin Jin   * <li>the Accessibility API (which {@link UiAutomationDriver} depends on)
1906f160bb942de53103e4f4ed54acaafe2da629fcfKevin Jin   * does not include off-screen children, but may include invisible on-screen
1916f160bb942de53103e4f4ed54acaafe2da629fcfKevin Jin   * children.</li>
1926f160bb942de53103e4f4ed54acaafe2da629fcfKevin Jin   * </ul>
193dfc316e1bfb37148c50947c46f5aaed5cb2e708aKevin Jin   * <p>
194dfc316e1bfb37148c50947c46f5aaed5cb2e708aKevin Jin   * Another discrepancy between {@link InstrumentationDriver}
195dfc316e1bfb37148c50947c46f5aaed5cb2e708aKevin Jin   * {@link UiAutomationDriver} is the order of children. The Accessibility API
196dfc316e1bfb37148c50947c46f5aaed5cb2e708aKevin Jin   * returns children in the order of layout (see
197dfc316e1bfb37148c50947c46f5aaed5cb2e708aKevin Jin   * {@link android.view.ViewGroup#addChildrenForAccessibility}, which is added
198dfc316e1bfb37148c50947c46f5aaed5cb2e708aKevin Jin   * in API16).
199dfc316e1bfb37148c50947c46f5aaed5cb2e708aKevin Jin   * </p>
200f9c6c5063b38b623679e47d7095cccddb0481319Kevin Jin   */
2016f160bb942de53103e4f4ed54acaafe2da629fcfKevin Jin  List<? extends UiElement> getChildren(Predicate<? super UiElement> predicate);
202f9c6c5063b38b623679e47d7095cccddb0481319Kevin Jin
203f9c6c5063b38b623679e47d7095cccddb0481319Kevin Jin  /**
204f9c6c5063b38b623679e47d7095cccddb0481319Kevin Jin   * Filters out invisible children.
205f9c6c5063b38b623679e47d7095cccddb0481319Kevin Jin   */
206f9c6c5063b38b623679e47d7095cccddb0481319Kevin Jin  Predicate<UiElement> VISIBLE = new Predicate<UiElement>() {
207f9c6c5063b38b623679e47d7095cccddb0481319Kevin Jin    @Override
208f9c6c5063b38b623679e47d7095cccddb0481319Kevin Jin    public boolean apply(UiElement element) {
209f9c6c5063b38b623679e47d7095cccddb0481319Kevin Jin      return element.isVisible();
210f9c6c5063b38b623679e47d7095cccddb0481319Kevin Jin    }
211f9c6c5063b38b623679e47d7095cccddb0481319Kevin Jin
212f9c6c5063b38b623679e47d7095cccddb0481319Kevin Jin    @Override
213f9c6c5063b38b623679e47d7095cccddb0481319Kevin Jin    public String toString() {
214f9c6c5063b38b623679e47d7095cccddb0481319Kevin Jin      return "VISIBLE";
215f9c6c5063b38b623679e47d7095cccddb0481319Kevin Jin    }
216f9c6c5063b38b623679e47d7095cccddb0481319Kevin Jin  };
217f9c6c5063b38b623679e47d7095cccddb0481319Kevin Jin
2180d7b67b43f83536708a6ae0330e739744049a48eKevin Jin  /**
219f9c6c5063b38b623679e47d7095cccddb0481319Kevin Jin   * Gets the parent.
2200d7b67b43f83536708a6ae0330e739744049a48eKevin Jin   */
2210d7b67b43f83536708a6ae0330e739744049a48eKevin Jin  UiElement getParent();
22274676fdd3c8a9e599eddd13bea56898674d9916aKevin Jin
22374676fdd3c8a9e599eddd13bea56898674d9916aKevin Jin  /**
22474676fdd3c8a9e599eddd13bea56898674d9916aKevin Jin   * Gets the {@link InputInjector} for injecting InputEvent.
22574676fdd3c8a9e599eddd13bea56898674d9916aKevin Jin   */
22674676fdd3c8a9e599eddd13bea56898674d9916aKevin Jin  InputInjector getInjector();
22757e46577852ffa1dde4662f6018f7fbcfacb6148Thanh Le}
228