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