diff --git a/src/main/java/io/appium/java_client/pagefactory/AndroidBy.java b/src/main/java/io/appium/java_client/pagefactory/AndroidBy.java index b40acdd07..180f38e30 100644 --- a/src/main/java/io/appium/java_client/pagefactory/AndroidBy.java +++ b/src/main/java/io/appium/java_client/pagefactory/AndroidBy.java @@ -58,6 +58,14 @@ */ String tagName() default ""; + /** + * It is an Android view tag (mapped from React Native {@code testID} and similar). + * Corresponds to {@link io.appium.java_client.AppiumBy#androidViewTag(String)}. + * + * @return a desired Android view tag + */ + String viewTag() default ""; + /** * It is a xpath to the target element. * diff --git a/src/main/java/io/appium/java_client/pagefactory/AndroidFindBy.java b/src/main/java/io/appium/java_client/pagefactory/AndroidFindBy.java index aa245d971..c49c68eaa 100644 --- a/src/main/java/io/appium/java_client/pagefactory/AndroidFindBy.java +++ b/src/main/java/io/appium/java_client/pagefactory/AndroidFindBy.java @@ -73,6 +73,14 @@ */ String tagName() default ""; + /** + * It is an Android view tag (mapped from React Native {@code testID} and similar). + * Corresponds to {@link io.appium.java_client.AppiumBy#androidViewTag(String)}. + * + * @return a desired Android view tag + */ + String viewTag() default ""; + /** * It is a desired data matcher expression. * diff --git a/src/main/java/io/appium/java_client/pagefactory/bys/builder/Strategies.java b/src/main/java/io/appium/java_client/pagefactory/bys/builder/Strategies.java index 590db8278..35522eec1 100644 --- a/src/main/java/io/appium/java_client/pagefactory/bys/builder/Strategies.java +++ b/src/main/java/io/appium/java_client/pagefactory/bys/builder/Strategies.java @@ -59,6 +59,11 @@ enum Strategies { return By.tagName(getValue(annotation, this)); } }, + BY_VIEW_TAG("viewTag") { + @Override By getBy(Annotation annotation) { + return AppiumBy.androidViewTag(getValue(annotation, this)); + } + }, BYNAME("name") { @Override By getBy(Annotation annotation) { return AppiumBy.name(getValue(annotation, this)); diff --git a/src/test/java/io/appium/java_client/pagefactory_tests/AndroidViewTagFindByTest.java b/src/test/java/io/appium/java_client/pagefactory_tests/AndroidViewTagFindByTest.java new file mode 100644 index 000000000..418362d54 --- /dev/null +++ b/src/test/java/io/appium/java_client/pagefactory_tests/AndroidViewTagFindByTest.java @@ -0,0 +1,51 @@ +/* + * 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.pagefactory_tests; + +import io.appium.java_client.AppiumBy; +import io.appium.java_client.pagefactory.AndroidFindBy; +import io.appium.java_client.pagefactory.DefaultElementByBuilder; +import io.appium.java_client.remote.AutomationName; +import io.appium.java_client.remote.MobilePlatform; +import org.junit.jupiter.api.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; + +import java.lang.reflect.Field; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class AndroidViewTagFindByTest { + + static class Page { + @AndroidFindBy(viewTag = "login-button") + private WebElement loginButton; + } + + @Test + void androidFindByViewTagBuildsAndroidViewTagLocator() throws Exception { + Field field = Page.class.getDeclaredField("loginButton"); + DefaultElementByBuilder builder = + new DefaultElementByBuilder(MobilePlatform.ANDROID, AutomationName.ANDROID_UIAUTOMATOR2); + builder.setAnnotated(field); + By by = builder.buildBy(); + + // Single AndroidFindBy strategies are wrapped in ByChained by DefaultElementByBuilder + assertTrue(by.toString().contains(AppiumBy.androidViewTag("login-button").toString()), + () -> "expected viewTag locator in " + by); + } +}