diff --git a/src/main/java/io/appium/java_client/FindsByAndroidViewTag.java b/src/main/java/io/appium/java_client/FindsByAndroidViewTag.java new file mode 100644 index 000000000..b1db5c432 --- /dev/null +++ b/src/main/java/io/appium/java_client/FindsByAndroidViewTag.java @@ -0,0 +1,52 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.appium.java_client; + +import org.openqa.selenium.NoSuchElementException; +import org.openqa.selenium.WebDriverException; +import org.openqa.selenium.WebElement; + +import java.util.List; + +public interface FindsByAndroidViewTag extends FindsByFluentSelector { + /** + * Method performs the searching for a single element by view tag selector + * and value of the given selector. + * + * @param using an view tag selector + * @return The first element that matches the given selector + * + * @throws WebDriverException This method is not applicable with browser/webview UI. + * @throws NoSuchElementException when no one element is found + */ + default T findElementByAndroidViewTag(String using) { + return findElement(MobileSelector.ANDROID_VIEWTAG.toString(), using); + } + + /** + * Method performs the searching for a list of elements by view tag selector + * and value of the given selector. + * + * @param using an view tag selector + * @return a list of elements that match the given selector + * + * @throws WebDriverException This method is not applicable with browser/webview UI. + */ + default List findElementsByAndroidViewTag(String using) { + return findElements(MobileSelector.ANDROID_VIEWTAG.toString(), using); + } +} diff --git a/src/main/java/io/appium/java_client/MobileBy.java b/src/main/java/io/appium/java_client/MobileBy.java index 3928799be..6a65034a3 100644 --- a/src/main/java/io/appium/java_client/MobileBy.java +++ b/src/main/java/io/appium/java_client/MobileBy.java @@ -121,6 +121,16 @@ public static By windowsAutomation(final String windowsAutomation) { return new ByWindowsAutomation(windowsAutomation); } + /** + * This locator strategy is available in Espresso Driver mode. + * @since Appium 1.8.2 beta + * @param tag is an view tag string + * @return an instance of {@link ByAndroidViewTag} + */ + public static By AndroidViewTag(final String tag) { + return new ByAndroidViewTag(tag); + } + /** * This locator strategy is available only if OpenCV libraries and * NodeJS bindings are installed on the server machine. @@ -561,6 +571,69 @@ protected ByImage(String b64Template) { return "By.Image: " + getLocatorString(); } } + + public static class ByAndroidViewTag extends MobileBy implements Serializable { + + public ByAndroidViewTag(String tag) { + super(MobileSelector.ANDROID_VIEWTAG, tag); + } + + /** + * {@inheritDoc} + * + * @throws WebDriverException when current session doesn't support the given selector or when + * value of the selector is not consistent. + * @throws IllegalArgumentException when it is impossible to find something on the given + * {@link SearchContext} instance + */ + @SuppressWarnings("unchecked") + @Override + public List findElements(SearchContext context) throws WebDriverException, + IllegalArgumentException { + Class contextClass = context.getClass(); + + if (FindsByAndroidViewTag.class.isAssignableFrom(contextClass)) { + return FindsByAndroidViewTag.class.cast(context) + .findElementsByAndroidViewTag(getLocatorString()); + } + + if (FindsByFluentSelector.class.isAssignableFrom(contextClass)) { + return super.findElements(context); + } + + throw formIllegalArgumentException(contextClass, FindsByAndroidViewTag.class, + FindsByFluentSelector.class); + } + + /** + * {@inheritDoc} + * + * @throws WebDriverException when current session doesn't support the given selector or when + * value of the selector is not consistent. + * @throws IllegalArgumentException when it is impossible to find something on the given + * {@link SearchContext} instance + */ + @Override public WebElement findElement(SearchContext context) throws WebDriverException, + IllegalArgumentException { + Class contextClass = context.getClass(); + + if (FindsByAndroidViewTag.class.isAssignableFrom(contextClass)) { + return FindsByAndroidViewTag.class.cast(context) + .findElementByAndroidViewTag(getLocatorString()); + } + + if (FindsByFluentSelector.class.isAssignableFrom(contextClass)) { + return super.findElement(context); + } + + throw formIllegalArgumentException(contextClass, FindsByAndroidViewTag.class, + FindsByFluentSelector.class); + } + + @Override public String toString() { + return "By.AndroidViewTag: " + getLocatorString(); + } + } } diff --git a/src/main/java/io/appium/java_client/MobileSelector.java b/src/main/java/io/appium/java_client/MobileSelector.java index acc07343c..f7d7bbb49 100644 --- a/src/main/java/io/appium/java_client/MobileSelector.java +++ b/src/main/java/io/appium/java_client/MobileSelector.java @@ -23,7 +23,8 @@ public enum MobileSelector { IOS_PREDICATE_STRING("-ios predicate string"), IOS_CLASS_CHAIN("-ios class chain"), WINDOWS_UI_AUTOMATION("-windows uiautomation"), - IMAGE("-image"); + IMAGE("-image"), + ANDROID_VIEWTAG("-android viewtag"); private final String selector; diff --git a/src/main/java/io/appium/java_client/android/AndroidDriver.java b/src/main/java/io/appium/java_client/android/AndroidDriver.java index de15bc20c..626ab95a2 100644 --- a/src/main/java/io/appium/java_client/android/AndroidDriver.java +++ b/src/main/java/io/appium/java_client/android/AndroidDriver.java @@ -27,6 +27,7 @@ import io.appium.java_client.AppiumDriver; import io.appium.java_client.CommandExecutionHelper; import io.appium.java_client.FindsByAndroidUIAutomator; +import io.appium.java_client.FindsByAndroidViewTag; import io.appium.java_client.HasOnScreenKeyboard; import io.appium.java_client.LocksDevice; import io.appium.java_client.android.connection.HasNetworkConnection; @@ -61,7 +62,8 @@ public class AndroidDriver extends AppiumDriver implements PressesKey, HasNetworkConnection, PushesFiles, StartsActivity, - FindsByAndroidUIAutomator, LocksDevice, HasAndroidSettings, HasAndroidDeviceDetails, + FindsByAndroidUIAutomator, FindsByAndroidViewTag, + LocksDevice, HasAndroidSettings, HasAndroidDeviceDetails, HasSupportedPerformanceDataType, AuthenticatesByFinger, HasOnScreenKeyboard, CanRecordScreen, SupportsSpecialEmulatorCommands, SupportsNetworkStateManagement, ListensToLogcatMessages, HasAndroidClipboard,