diff --git a/docs/Page-objects.md b/docs/Page-objects.md index 2f97d2601..7729bd14c 100644 --- a/docs/Page-objects.md +++ b/docs/Page-objects.md @@ -80,7 +80,10 @@ List someElements; # Also it is possible to define chained or any possible locators. -- Chained +## - Chained + +### If you use build versions < 5.x.x + ```java import org.openqa.selenium.remote.RemoteWebElement; import io.appium.java_client.pagefactory.*; @@ -98,7 +101,52 @@ RemoteWebElement someElement; List someElements; ``` -- Any possible +### If you use build versions >= 5.x.x + +```java +import org.openqa.selenium.remote.RemoteWebElement; +import io.appium.java_client.pagefactory.*; +import org.openqa.selenium.support.FindBys; +import org.openqa.selenium.support.FindBy; + +@FindBys({@FindBy(someStrategy1), @FindBy(someStrategy2)}) +@AndroidFindBy(someStrategy1) @AndroidFindBy(someStrategy2) +@iOSFindBy(someStrategy1) @iOSFindBy(someStrategy2) +RemoteWebElement someElement; + +@FindBys({@FindBy(someStrategy1), @FindBy(someStrategy2)}) +@AndroidFindBy(someStrategy1) @AndroidFindBy(someStrategy2) +@iOSFindBy(someStrategy1) @iOSFindBy(someStrategy2) +List someElements; +``` + +or + +```java +import org.openqa.selenium.remote.RemoteWebElement; +import io.appium.java_client.pagefactory.*; +import org.openqa.selenium.support.FindBys; +import org.openqa.selenium.support.FindBy; + +import static io.appium.java_client.pagefactory.LocatorGroupStrategy.CHAIN; + +@HowToUseLocators(androidAutomation = CHAIN, iOSAutomation = CHAIN) +@FindBys({@FindBy(someStrategy1), @FindBy(someStrategy2)}) +@AndroidFindBy(someStrategy1) @AndroidFindBy(someStrategy2) +@iOSFindBy(someStrategy1) @iOSFindBy(someStrategy2) +RemoteWebElement someElement; + +@HowToUseLocators(androidAutomation = CHAIN, iOSAutomation = CHAIN) +@FindBys({@FindBy(someStrategy1), @FindBy(someStrategy2)}) +@AndroidFindBy(someStrategy1) @AndroidFindBy(someStrategy2) +@iOSFindBy(someStrategy1) @iOSFindBy(someStrategy2) +List someElements; +``` + +## - Any possible + +### If you use build versions < 5.x.x + ```java import org.openqa.selenium.remote.RemoteWebElement; import io.appium.java_client.pagefactory.*; @@ -116,6 +164,78 @@ RemoteWebElement someElement; List someElements; ``` +### If you use build versions >= 5.x.x + +```java +import org.openqa.selenium.remote.RemoteWebElement; +import io.appium.java_client.pagefactory.*; +import org.openqa.selenium.support.FindBy; +import org.openqa.selenium.support.FindByAll; + +import static io.appium.java_client.pagefactory.LocatorGroupStrategy.ALL_POSSIBLE; + +@HowToUseLocators(androidAutomation = ALL_POSSIBLE, iOSAutomation = ALL_POSSIBLE) +@FindAll{@FindBy(someStrategy1), @FindBy(someStrategy2)}) +@AndroidFindBy(someStrategy1) @AndroidFindBy(someStrategy2) +@iOSFindBy(someStrategy1) @iOSFindBy(someStrategy2) +RemoteWebElement someElement; + +@HowToUseLocators(androidAutomation = ALL_POSSIBLE, iOSAutomation = ALL_POSSIBLE) +@FindAll({@FindBy(someStrategy1), @FindBy(someStrategy2)}) +@AndroidFindBy(someStrategy1) @AndroidFindBy(someStrategy2) +@iOSFindBy(someStrategy1) @iOSFindBy(someStrategy2) +List someElements; +``` + +## Also possible combined variants: + +```java +import org.openqa.selenium.remote.RemoteWebElement; +import io.appium.java_client.pagefactory.*; +import org.openqa.selenium.support.FindBy; +import org.openqa.selenium.support.FindByAll; + +import static io.appium.java_client.pagefactory.LocatorGroupStrategy.CHAIN; +import static io.appium.java_client.pagefactory.LocatorGroupStrategy.ALL_POSSIBLE; + +@HowToUseLocators(androidAutomation = CHAIN, iOSAutomation = ALL_POSSIBLE) +@FindAll{@FindBy(someStrategy1), @FindBy(someStrategy2)}) +@AndroidFindBy(someStrategy1) @AndroidFindBy(someStrategy2) +@iOSFindBy(someStrategy1) @iOSFindBy(someStrategy2) +RemoteWebElement someElement; + +@HowToUseLocators(androidAutomation = CHAIN, iOSAutomation = ALL_POSSIBLE) +@FindAll({@FindBy(someStrategy1), @FindBy(someStrategy2)}) +@AndroidFindBy(someStrategy1) @AndroidFindBy(someStrategy2) +@iOSFindBy(someStrategy1) @iOSFindBy(someStrategy2) +List someElements; +``` + +or + +```java +import org.openqa.selenium.remote.RemoteWebElement; +import io.appium.java_client.pagefactory.*; +import org.openqa.selenium.support.FindBy; +import org.openqa.selenium.support.FindByAll; + +import static io.appium.java_client.pagefactory.LocatorGroupStrategy.ALL_POSSIBLE; + +@HowToUseLocators(iOSAutomation = ALL_POSSIBLE) +@FindAll{@FindBy(someStrategy1), @FindBy(someStrategy2)}) +@AndroidFindBy(someStrategy1) @AndroidFindBy(someStrategy2) //this is the chain +//by default +@iOSFindBy(someStrategy1) @iOSFindBy(someStrategy2) +RemoteWebElement someElement; + +@HowToUseLocators(iOSAutomation = ALL_POSSIBLE) +@FindAll({@FindBy(someStrategy1), @FindBy(someStrategy2)}) +@AndroidFindBy(someStrategy1) @AndroidFindBy(someStrategy2) //this is the chain +//by default +@iOSFindBy(someStrategy1) @iOSFindBy(someStrategy2) +List someElements; +``` + # Appium Java client is integrated with Selenium PageFactory by AppiumFieldDecorator. Object fields are populated as below: diff --git a/src/main/java/io/appium/java_client/AppiumDriver.java b/src/main/java/io/appium/java_client/AppiumDriver.java index 2eacf2e1f..7b023405b 100644 --- a/src/main/java/io/appium/java_client/AppiumDriver.java +++ b/src/main/java/io/appium/java_client/AppiumDriver.java @@ -14,13 +14,10 @@ * limitations under the License. */ - package io.appium.java_client; import static com.google.common.base.Preconditions.checkNotNull; -import static io.appium.java_client.MobileCommand.GET_SESSION; - import com.google.common.collect.ImmutableMap; import io.appium.java_client.remote.AppiumCommandExecutor; @@ -58,18 +55,17 @@ import java.util.Map; import java.util.Set; - /** - * @param the required type of class which implement {@link org.openqa.selenium.WebElement}. - * Instances of the defined type will be returned via findElement* and findElements* - * Warning (!!!). Allowed types: - * {@link org.openqa.selenium.WebElement} - * {@link io.appium.java_client.TouchableElement} - * {@link org.openqa.selenium.remote.RemoteWebElement} - * {@link io.appium.java_client.MobileElement} and its subclasses that designed - * specifically - * for each target mobile OS (still Android and iOS) - */ +* @param the required type of class which implement {@link org.openqa.selenium.WebElement}. + * Instances of the defined type will be returned via findElement* and findElements* + * Warning (!!!). Allowed types: + * {@link org.openqa.selenium.WebElement} + * {@link io.appium.java_client.TouchableElement} + * {@link org.openqa.selenium.remote.RemoteWebElement} + * {@link io.appium.java_client.MobileElement} and its subclasses that designed + * specifically + * for each target mobile OS (still Android and iOS) +*/ @SuppressWarnings("unchecked") public abstract class AppiumDriver extends DefaultGenericMobileDriver { @@ -81,13 +77,13 @@ public abstract class AppiumDriver private ExecuteMethod executeMethod; /** - * @param executor is an instance of {@link org.openqa.selenium.remote.HttpCommandExecutor} - * or class that extends it. Default commands or another vendor-specific - * commands may be specified there. - * @param capabilities take a look - * at {@link org.openqa.selenium.Capabilities} + * @param executor is an instance of {@link org.openqa.selenium.remote.HttpCommandExecutor} + * or class that extends it. Default commands or another vendor-specific + * commands may be specified there. + * @param capabilities take a look + * at {@link org.openqa.selenium.Capabilities} * @param converterClazz is an instance of a class that extends - * {@link org.openqa.selenium.remote.internal.JsonToWebElementConverter}. It converts + * {@link org.openqa.selenium.remote.internal.JsonToWebElementConverter}. It converts * JSON response to an instance of * {@link org.openqa.selenium.WebElement} */ @@ -100,10 +96,10 @@ protected AppiumDriver(HttpCommandExecutor executor, Capabilities capabilities, this.remoteAddress = executor.getAddressOfRemoteServer(); try { Constructor constructor = - converterClazz.getConstructor(RemoteWebDriver.class); + converterClazz.getConstructor(RemoteWebDriver.class); this.setElementConverter(constructor.newInstance(this)); } catch (NoSuchMethodException | IllegalAccessException | InstantiationException - | InvocationTargetException e) { + | InvocationTargetException e) { throw new RuntimeException(e); } } @@ -116,7 +112,7 @@ public AppiumDriver(URL remoteAddress, Capabilities desiredCapabilities, public AppiumDriver(URL remoteAddress, HttpClient.Factory httpClientFactory, Capabilities desiredCapabilities, - Class converterClazz) { + Class converterClazz) { this(new AppiumCommandExecutor(MobileCommand.commandRepository, remoteAddress, httpClientFactory), desiredCapabilities, converterClazz); } @@ -129,7 +125,7 @@ public AppiumDriver(AppiumDriverLocalService service, Capabilities desiredCapabi public AppiumDriver(AppiumDriverLocalService service, HttpClient.Factory httpClientFactory, Capabilities desiredCapabilities, - Class converterClazz) { + Class converterClazz) { this(new AppiumCommandExecutor(MobileCommand.commandRepository, service, httpClientFactory), desiredCapabilities, converterClazz); } @@ -141,14 +137,14 @@ public AppiumDriver(AppiumServiceBuilder builder, Capabilities desiredCapabiliti public AppiumDriver(AppiumServiceBuilder builder, HttpClient.Factory httpClientFactory, Capabilities desiredCapabilities, - Class converterClazz) { + Class converterClazz) { this(builder.build(), httpClientFactory, desiredCapabilities, converterClazz); } public AppiumDriver(HttpClient.Factory httpClientFactory, Capabilities desiredCapabilities, Class converterClazz) { - this(AppiumDriverLocalService.buildDefaultService(), httpClientFactory, desiredCapabilities, - converterClazz); + this(AppiumDriverLocalService.buildDefaultService(), httpClientFactory, + desiredCapabilities, converterClazz); } public AppiumDriver(Capabilities desiredCapabilities, @@ -158,8 +154,8 @@ public AppiumDriver(Capabilities desiredCapabilities, /** * @param originalCapabilities the given {@link Capabilities}. - * @param newPlatform a {@link MobileCapabilityType#PLATFORM_NAME} value which has - * to be set up + * @param newPlatform a {@link MobileCapabilityType#PLATFORM_NAME} value which has + * to be set up * @return {@link Capabilities} with changed mobile platform value */ protected static Capabilities substituteMobilePlatform(Capabilities originalCapabilities, @@ -414,7 +410,7 @@ public void zoom(int x, int y) { @Override public DeviceRotation rotation() { Response response = execute(DriverCommand.GET_SCREEN_ROTATION); DeviceRotation deviceRotation = - new DeviceRotation((Map) response.getValue()); + new DeviceRotation((Map) response.getValue()); if (deviceRotation.getX() < 0 || deviceRotation.getY() < 0 || deviceRotation.getZ() < 0) { throw new WebDriverException("Unexpected orientation returned: " + deviceRotation); } @@ -428,7 +424,7 @@ public void zoom(int x, int y) { @Override public void rotate(ScreenOrientation orientation) { execute(DriverCommand.SET_SCREEN_ORIENTATION, - ImmutableMap.of("orientation", orientation.value().toUpperCase())); + ImmutableMap.of("orientation", orientation.value().toUpperCase())); } @Override public ScreenOrientation getOrientation() { @@ -464,12 +460,4 @@ private TouchAction createTap(int x, int y, int duration) { public URL getRemoteAddress() { return remoteAddress; } - - /** - * @return a map with values that hold session details. - */ - public Map getSessionDetails() { - Response response = execute(GET_SESSION); - return (Map) response.getValue(); - } } diff --git a/src/main/java/io/appium/java_client/HasSessionDetails.java b/src/main/java/io/appium/java_client/HasSessionDetails.java new file mode 100644 index 000000000..618a32304 --- /dev/null +++ b/src/main/java/io/appium/java_client/HasSessionDetails.java @@ -0,0 +1,38 @@ +/* + * 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 static io.appium.java_client.MobileCommand.GET_SESSION; + +import org.openqa.selenium.remote.Response; + +import java.util.Map; + +public interface HasSessionDetails extends ExecutesMethod { + /** + * @return a map with values that hold session details. + * + */ + default Map getSessionDetails() { + Response response = execute(GET_SESSION); + return (Map) response.getValue(); + } + + default Object getSessionDetail(String detail) { + return getSessionDetails().get(detail); + } +} diff --git a/src/main/java/io/appium/java_client/MobileDriver.java b/src/main/java/io/appium/java_client/MobileDriver.java index bdda35e23..44fa065ff 100644 --- a/src/main/java/io/appium/java_client/MobileDriver.java +++ b/src/main/java/io/appium/java_client/MobileDriver.java @@ -37,7 +37,8 @@ public interface MobileDriver extends WebDriver, PerformsTouchActions, ContextAware, Rotatable, FindsByAccessibilityId, LocationContext, DeviceActionShortcuts, TouchShortcuts, InteractsWithFiles, InteractsWithApps, HasAppStrings, FindsByClassName, FindsByCssSelector, FindsById, - FindsByLinkText, FindsByName, FindsByTagName, FindsByXPath, FindsByFluentSelector, ExecutesMethod { + FindsByLinkText, FindsByName, FindsByTagName, FindsByXPath, FindsByFluentSelector, ExecutesMethod, + HasSessionDetails { List findElements(By by); diff --git a/src/main/java/io/appium/java_client/pagefactory/AndroidFindAll.java b/src/main/java/io/appium/java_client/pagefactory/AndroidFindAll.java index 5b24ac981..3f3327ee4 100644 --- a/src/main/java/io/appium/java_client/pagefactory/AndroidFindAll.java +++ b/src/main/java/io/appium/java_client/pagefactory/AndroidFindAll.java @@ -26,7 +26,12 @@ * series of {@link io.appium.java_client.pagefactory.AndroidFindBy} tags * It will then search for all elements that match any criteria. Note that elements * are not guaranteed to be in document order. + * It is deprecated. Set of {@link io.appium.java_client.pagefactory.AndroidFindBy} + * can be defined without this annotation. To define the correct way how to use + * the defined set please take a look at {@link HowToUseLocators}. The article. + * https://docs.oracle.com/javase/tutorial/java/annotations/repeating.html. */ +@Deprecated @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE}) public @interface AndroidFindAll { /** 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 eb5fcabdc..501cca7c7 100644 --- a/src/main/java/io/appium/java_client/pagefactory/AndroidFindBy.java +++ b/src/main/java/io/appium/java_client/pagefactory/AndroidFindBy.java @@ -17,6 +17,7 @@ package io.appium.java_client.pagefactory; import java.lang.annotation.ElementType; +import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @@ -30,6 +31,7 @@ * using Android UI selectors, accessibility, id, name, class name, tag and xpath */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE}) +@Repeatable(AndroidFindBySet.class) public @interface AndroidFindBy { /** * It is an is Android UIAutomator string. diff --git a/src/main/java/io/appium/java_client/pagefactory/AndroidFindBySet.java b/src/main/java/io/appium/java_client/pagefactory/AndroidFindBySet.java new file mode 100644 index 000000000..863b619d0 --- /dev/null +++ b/src/main/java/io/appium/java_client/pagefactory/AndroidFindBySet.java @@ -0,0 +1,36 @@ +/* + * 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; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Defines set of chained/possible locators. Each one locator + * should be defined with {@link io.appium.java_client.pagefactory.AndroidFindBy} + */ +@Target(value = {ElementType.TYPE, ElementType.FIELD}) +@Retention(value = RetentionPolicy.RUNTIME) +public @interface AndroidFindBySet { + /** + * @return an array of {@link io.appium.java_client.pagefactory.AndroidFindBy} which builds a sequence of + * the chained searching for elements or a set of possible locators + */ + AndroidFindBy[] value(); +} diff --git a/src/main/java/io/appium/java_client/pagefactory/AndroidFindBys.java b/src/main/java/io/appium/java_client/pagefactory/AndroidFindBys.java index cf67c0f02..692d64da2 100644 --- a/src/main/java/io/appium/java_client/pagefactory/AndroidFindBys.java +++ b/src/main/java/io/appium/java_client/pagefactory/AndroidFindBys.java @@ -24,7 +24,12 @@ /** * Used to mark a field on a Page Object to indicate that lookup should use * a series of {@link io.appium.java_client.pagefactory.AndroidFindBy} tags. + * It is deprecated. Set of {@link io.appium.java_client.pagefactory.AndroidFindBy} + * can be defined without this annotation. To define the correct way how to use + * the defined set please take a look at {@link HowToUseLocators}. The article. + * https://docs.oracle.com/javase/tutorial/java/annotations/repeating.html. */ +@Deprecated @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE}) public @interface AndroidFindBys { /** diff --git a/src/main/java/io/appium/java_client/pagefactory/AppiumFieldDecorator.java b/src/main/java/io/appium/java_client/pagefactory/AppiumFieldDecorator.java index 08fb55c39..f26c221f1 100644 --- a/src/main/java/io/appium/java_client/pagefactory/AppiumFieldDecorator.java +++ b/src/main/java/io/appium/java_client/pagefactory/AppiumFieldDecorator.java @@ -17,11 +17,10 @@ package io.appium.java_client.pagefactory; import static io.appium.java_client.pagefactory.utils.ProxyFactory.getEnhancedProxy; -import static io.appium.java_client.pagefactory.utils.WebDriverUnpackUtility.getAutomation; -import static io.appium.java_client.pagefactory.utils.WebDriverUnpackUtility.getPlatform; import static io.appium.java_client.pagefactory.utils.WebDriverUnpackUtility .unpackWebDriverFromSearchContext; +import io.appium.java_client.HasSessionDetails; import io.appium.java_client.MobileElement; import io.appium.java_client.TouchableElement; import io.appium.java_client.android.AndroidDriver; @@ -94,6 +93,24 @@ public class AppiumFieldDecorator implements FieldDecorator { private final String automation; private final TimeOutDuration timeOutDuration; + private static String extractSessionData(WebDriver driver, String parameter) { + if (driver == null) { + return null; + } + + if (!(driver instanceof HasSessionDetails)) { + return null; + } + + Object parameterValue = HasSessionDetails.class.cast(driver).getSessionDetail(parameter); + + if (parameterValue == null) { + return null; + } + + return String.valueOf(parameterValue); + } + public AppiumFieldDecorator(SearchContext context, long implicitlyWaitTimeOut, TimeUnit timeUnit) { this(context, new TimeOutDuration(implicitlyWaitTimeOut, timeUnit)); @@ -109,8 +126,8 @@ public AppiumFieldDecorator(SearchContext context, long implicitlyWaitTimeOut, */ public AppiumFieldDecorator(SearchContext context, TimeOutDuration timeOutDuration) { this.originalDriver = unpackWebDriverFromSearchContext(context); - platform = getPlatform(originalDriver); - automation = getAutomation(originalDriver); + platform = extractSessionData(originalDriver, "platformName"); + automation = extractSessionData(originalDriver, "automationName"); this.timeOutDuration = timeOutDuration; defaultElementFieldDecoracor = new DefaultFieldDecorator( diff --git a/src/main/java/io/appium/java_client/pagefactory/DefaultElementByBuilder.java b/src/main/java/io/appium/java_client/pagefactory/DefaultElementByBuilder.java index c205c0dee..70c94958b 100644 --- a/src/main/java/io/appium/java_client/pagefactory/DefaultElementByBuilder.java +++ b/src/main/java/io/appium/java_client/pagefactory/DefaultElementByBuilder.java @@ -108,17 +108,19 @@ private static void checkDisallowedAnnotationPairs(Annotation a1, Annotation a2) @Override protected By buildMobileNativeBy() { AnnotatedElement annotatedElement = annotatedElementContainer.getAnnotated(); if (isSelendroidAutomation()) { - SelendroidFindBy selendroidFindBy = - annotatedElement.getAnnotation(SelendroidFindBy.class); + SelendroidFindBy[] selendroidFindByArray = + annotatedElement.getAnnotationsByType(SelendroidFindBy.class); + //should be kept for some time SelendroidFindBys selendroidFindBys = annotatedElement.getAnnotation(SelendroidFindBys.class); SelendroidFindAll selendroidFindByAll = annotatedElement.getAnnotation(SelendroidFindAll.class); - if (selendroidFindBy != null) { - return createBy(new Annotation[] {selendroidFindBy}, HowToUseSelectors.USE_ONE); + if (selendroidFindByArray != null && selendroidFindByArray.length == 1) { + return createBy(new Annotation[] {selendroidFindByArray[0]}, HowToUseSelectors.USE_ONE); } + //should be kept for some time if (selendroidFindBys != null) { return createBy(selendroidFindBys.value(), HowToUseSelectors.BUILD_CHAINED); } @@ -126,17 +128,32 @@ private static void checkDisallowedAnnotationPairs(Annotation a1, Annotation a2) if (selendroidFindByAll != null) { return createBy(selendroidFindByAll.value(), HowToUseSelectors.USE_ANY); } + + if (selendroidFindByArray != null && selendroidFindByArray.length > 0) { + HowToUseLocators howToUseLocators = annotatedElement.getAnnotation(HowToUseLocators.class); + if (howToUseLocators == null) { + return createBy(selendroidFindByArray, HowToUseSelectors.BUILD_CHAINED); + } + + if (howToUseLocators.selendroidAutomation() == LocatorGroupStrategy.ALL_POSSIBLE) { + return createBy(selendroidFindByArray, HowToUseSelectors.USE_ANY); + } + + return createBy(selendroidFindByArray, HowToUseSelectors.BUILD_CHAINED); + } } if (isAndroid()) { - AndroidFindBy androidFindBy = annotatedElement.getAnnotation(AndroidFindBy.class); + AndroidFindBy[] androidFindByArray = annotatedElement.getAnnotationsByType(AndroidFindBy.class); + //should be kept for some time AndroidFindBys androidFindBys = annotatedElement.getAnnotation(AndroidFindBys.class); AndroidFindAll androidFindAll = annotatedElement.getAnnotation(AndroidFindAll.class); - if (androidFindBy != null) { - return createBy(new Annotation[] {androidFindBy}, HowToUseSelectors.USE_ONE); + if (androidFindByArray != null && androidFindByArray.length == 1) { + return createBy(new Annotation[] {androidFindByArray[0]}, HowToUseSelectors.USE_ONE); } + //should be kept for some time if (androidFindBys != null) { return createBy(androidFindBys.value(), HowToUseSelectors.BUILD_CHAINED); } @@ -144,17 +161,32 @@ private static void checkDisallowedAnnotationPairs(Annotation a1, Annotation a2) if (androidFindAll != null) { return createBy(androidFindAll.value(), HowToUseSelectors.USE_ANY); } + + if (androidFindByArray != null && androidFindByArray.length > 0) { + HowToUseLocators howToUseLocators = annotatedElement.getAnnotation(HowToUseLocators.class); + if (howToUseLocators == null) { + return createBy(androidFindByArray, HowToUseSelectors.BUILD_CHAINED); + } + + if (howToUseLocators.androidAutomation() == LocatorGroupStrategy.ALL_POSSIBLE) { + return createBy(androidFindByArray, HowToUseSelectors.USE_ANY); + } + + return createBy(androidFindByArray, HowToUseSelectors.BUILD_CHAINED); + } } if (isIOS()) { - iOSFindBy iOSFindBy = annotatedElement.getAnnotation(iOSFindBy.class); + iOSFindBy[] iOSFindByArray = annotatedElement.getAnnotationsByType(iOSFindBy.class); + //should be kept for some time iOSFindBys iOSFindBys = annotatedElement.getAnnotation(iOSFindBys.class); iOSFindAll iOSFindAll = annotatedElement.getAnnotation(iOSFindAll.class); - if (iOSFindBy != null) { - return createBy(new Annotation[] {iOSFindBy}, HowToUseSelectors.USE_ONE); + if (iOSFindByArray != null && iOSFindByArray.length == 1) { + return createBy(new Annotation[] {iOSFindByArray[0]}, HowToUseSelectors.USE_ONE); } + //should be kept for some time if (iOSFindBys != null) { return createBy(iOSFindBys.value(), HowToUseSelectors.BUILD_CHAINED); } @@ -162,6 +194,19 @@ private static void checkDisallowedAnnotationPairs(Annotation a1, Annotation a2) if (iOSFindAll != null) { return createBy(iOSFindAll.value(), HowToUseSelectors.USE_ANY); } + + if (iOSFindByArray != null && iOSFindByArray.length > 0) { + HowToUseLocators howToUseLocators = annotatedElement.getAnnotation(HowToUseLocators.class); + if (howToUseLocators == null) { + return createBy(iOSFindByArray, HowToUseSelectors.BUILD_CHAINED); + } + + if (howToUseLocators.iOSAutomation() == LocatorGroupStrategy.ALL_POSSIBLE) { + return createBy(iOSFindByArray, HowToUseSelectors.USE_ANY); + } + + return createBy(iOSFindByArray, HowToUseSelectors.BUILD_CHAINED); + } } return null; diff --git a/src/main/java/io/appium/java_client/pagefactory/HowToUseLocators.java b/src/main/java/io/appium/java_client/pagefactory/HowToUseLocators.java new file mode 100644 index 000000000..891ce1a1e --- /dev/null +++ b/src/main/java/io/appium/java_client/pagefactory/HowToUseLocators.java @@ -0,0 +1,46 @@ +/* + * 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; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE}) +public @interface HowToUseLocators { + /** + * @return the strategy which defines how to use locators which are described by + * the {@link AndroidFindBy} annotation. These annotations can define the chained searching + * or the searching by all possible locators. + */ + LocatorGroupStrategy androidAutomation() default LocatorGroupStrategy.CHAIN; + + /** + * @return the strategy which defines how to use locators which are described by + * the {@link SelendroidFindBy} annotation. These annotations can define the chained searching + * or the searching by all possible locators. + */ + LocatorGroupStrategy selendroidAutomation() default LocatorGroupStrategy.CHAIN; + + /** + * @return the strategy which defines how to use locators which are described by + * the {@link iOSFindBy} annotation. These annotations can define the chained searching + * or the searching by all possible locators. + */ + LocatorGroupStrategy iOSAutomation() default LocatorGroupStrategy.CHAIN; +} diff --git a/src/main/java/io/appium/java_client/pagefactory/LocatorGroupStrategy.java b/src/main/java/io/appium/java_client/pagefactory/LocatorGroupStrategy.java new file mode 100644 index 000000000..0b70cc8b0 --- /dev/null +++ b/src/main/java/io/appium/java_client/pagefactory/LocatorGroupStrategy.java @@ -0,0 +1,21 @@ +/* + * 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; + +public enum LocatorGroupStrategy { + CHAIN, ALL_POSSIBLE; +} diff --git a/src/main/java/io/appium/java_client/pagefactory/OverrideWidgetReader.java b/src/main/java/io/appium/java_client/pagefactory/OverrideWidgetReader.java index 52227732e..bfcc07a40 100644 --- a/src/main/java/io/appium/java_client/pagefactory/OverrideWidgetReader.java +++ b/src/main/java/io/appium/java_client/pagefactory/OverrideWidgetReader.java @@ -71,8 +71,8 @@ static Class getDefaultOrHTMLWidgetClass( static Class getMobileNativeWidgetClass(Class declaredClass, AnnotatedElement annotatedElement, String platform, String automation) { - String transformedPlatform = platform.toUpperCase().trim(); - String transformedAutomation = automation.toUpperCase().trim(); + String transformedPlatform = String.valueOf(platform).toUpperCase().trim(); + String transformedAutomation = String.valueOf(automation).toUpperCase().trim(); if (ANDROID.toUpperCase().equals(transformedPlatform) && AutomationName.SELENDROID .toUpperCase().equals(transformedAutomation)) { diff --git a/src/main/java/io/appium/java_client/pagefactory/SelendroidFindAll.java b/src/main/java/io/appium/java_client/pagefactory/SelendroidFindAll.java index dabcc6153..b9d67dd62 100644 --- a/src/main/java/io/appium/java_client/pagefactory/SelendroidFindAll.java +++ b/src/main/java/io/appium/java_client/pagefactory/SelendroidFindAll.java @@ -26,7 +26,12 @@ * series of {@link io.appium.java_client.pagefactory.SelendroidFindBy} tags * It will then search for all elements that match any criteria. Note that elements * are not guaranteed to be in document order. + * It is deprecated. Set of {@link io.appium.java_client.pagefactory.SelendroidFindBy} + * can be defined without this annotation. To define the correct way how to use + * the defined set please take a look at {@link HowToUseLocators}. The article. + * https://docs.oracle.com/javase/tutorial/java/annotations/repeating.html. */ +@Deprecated @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE}) public @interface SelendroidFindAll { /** diff --git a/src/main/java/io/appium/java_client/pagefactory/SelendroidFindBy.java b/src/main/java/io/appium/java_client/pagefactory/SelendroidFindBy.java index 371588ae8..be0cd7a10 100644 --- a/src/main/java/io/appium/java_client/pagefactory/SelendroidFindBy.java +++ b/src/main/java/io/appium/java_client/pagefactory/SelendroidFindBy.java @@ -17,6 +17,7 @@ package io.appium.java_client.pagefactory; import java.lang.annotation.ElementType; +import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @@ -30,6 +31,7 @@ * using Selendroid UI selectors like, id, name, class name, tag and xpath */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE}) +@Repeatable(SelendroidFindBySet.class) public @interface SelendroidFindBy { /** * It is an id of the target element. diff --git a/src/main/java/io/appium/java_client/pagefactory/SelendroidFindBySet.java b/src/main/java/io/appium/java_client/pagefactory/SelendroidFindBySet.java new file mode 100644 index 000000000..0fa8fa721 --- /dev/null +++ b/src/main/java/io/appium/java_client/pagefactory/SelendroidFindBySet.java @@ -0,0 +1,36 @@ +/* + * 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; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Defines set of chained/possible locators. Each one locator + * should be defined with {@link io.appium.java_client.pagefactory.SelendroidFindBy} + */ +@Target(value = {ElementType.TYPE, ElementType.FIELD}) +@Retention(value = RetentionPolicy.RUNTIME) +public @interface SelendroidFindBySet { + /** + * @return an array of {@link io.appium.java_client.pagefactory.SelendroidFindBy} which builds a sequence of + * the chained searching for elements or a set of possible locators + */ + SelendroidFindBy[] value(); +} diff --git a/src/main/java/io/appium/java_client/pagefactory/SelendroidFindBys.java b/src/main/java/io/appium/java_client/pagefactory/SelendroidFindBys.java index 50afadbf5..b0d7d9deb 100644 --- a/src/main/java/io/appium/java_client/pagefactory/SelendroidFindBys.java +++ b/src/main/java/io/appium/java_client/pagefactory/SelendroidFindBys.java @@ -24,7 +24,12 @@ /** * Used to mark a field on a Page Object to indicate that lookup should * use a series of {@link io.appium.java_client.pagefactory.SelendroidFindBy} tags. + * It is deprecated. Set of {@link io.appium.java_client.pagefactory.SelendroidFindBy} + * can be defined without this annotation. To define the correct way how to use + * the defined set please take a look at {@link HowToUseLocators}. The article. + * https://docs.oracle.com/javase/tutorial/java/annotations/repeating.html. */ +@Deprecated @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE}) public @interface SelendroidFindBys { /** diff --git a/src/main/java/io/appium/java_client/pagefactory/iOSFindAll.java b/src/main/java/io/appium/java_client/pagefactory/iOSFindAll.java index bd7abc8f7..a622a8246 100644 --- a/src/main/java/io/appium/java_client/pagefactory/iOSFindAll.java +++ b/src/main/java/io/appium/java_client/pagefactory/iOSFindAll.java @@ -26,7 +26,12 @@ * of {@link io.appium.java_client.pagefactory.iOSFindBy} tags * It will then search for all elements that match any criteria. Note that elements * are not guaranteed to be in document order. + * It is deprecated. Set of {@link io.appium.java_client.pagefactory.iOSFindBy} + * can be defined without this annotation. To define the correct way how to use + * the defined set please take a look at {@link HowToUseLocators}. The article. + * https://docs.oracle.com/javase/tutorial/java/annotations/repeating.html. */ +@Deprecated @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE}) public @interface iOSFindAll { /** diff --git a/src/main/java/io/appium/java_client/pagefactory/iOSFindBy.java b/src/main/java/io/appium/java_client/pagefactory/iOSFindBy.java index 0686cf9ef..f5fd649fa 100644 --- a/src/main/java/io/appium/java_client/pagefactory/iOSFindBy.java +++ b/src/main/java/io/appium/java_client/pagefactory/iOSFindBy.java @@ -17,6 +17,7 @@ package io.appium.java_client.pagefactory; import java.lang.annotation.ElementType; +import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @@ -30,6 +31,7 @@ * using iOS UI selectors, accessibility, id, name, class name, tag and xpath */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE}) +@Repeatable(iOSFindBySet.class) public @interface iOSFindBy { /** * It is is iOS UIAutomation string. diff --git a/src/main/java/io/appium/java_client/pagefactory/iOSFindBySet.java b/src/main/java/io/appium/java_client/pagefactory/iOSFindBySet.java new file mode 100644 index 000000000..28fecc160 --- /dev/null +++ b/src/main/java/io/appium/java_client/pagefactory/iOSFindBySet.java @@ -0,0 +1,36 @@ +/* + * 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; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Defines set of chained/possible locators. Each one locator + * should be defined with {@link io.appium.java_client.pagefactory.iOSFindBy} + */ +@Target(value = {ElementType.TYPE, ElementType.FIELD}) +@Retention(value = RetentionPolicy.RUNTIME) +public @interface iOSFindBySet { + /** + * @return an array of {@link io.appium.java_client.pagefactory.iOSFindBy} which builds a sequence of + * the chained searching for elements or a set of possible locators + */ + iOSFindBy[] value(); +} diff --git a/src/main/java/io/appium/java_client/pagefactory/iOSFindBys.java b/src/main/java/io/appium/java_client/pagefactory/iOSFindBys.java index 9e06d2392..51fb3fe68 100644 --- a/src/main/java/io/appium/java_client/pagefactory/iOSFindBys.java +++ b/src/main/java/io/appium/java_client/pagefactory/iOSFindBys.java @@ -24,7 +24,12 @@ /** * Used to mark a field on a Page Object to indicate that lookup should use * a series of {@link io.appium.java_client.pagefactory.iOSFindBy} tags. + * It is deprecated. Set of {@link io.appium.java_client.pagefactory.iOSFindBy} + * can be defined without this annotation. To define the correct way how to use + * the defined set please take a look at {@link HowToUseLocators}. The article. + * https://docs.oracle.com/javase/tutorial/java/annotations/repeating.html. */ +@Deprecated @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE}) public @interface iOSFindBys { /** diff --git a/src/main/java/io/appium/java_client/pagefactory/utils/WebDriverUnpackUtility.java b/src/main/java/io/appium/java_client/pagefactory/utils/WebDriverUnpackUtility.java index 03447eace..246ae06cf 100644 --- a/src/main/java/io/appium/java_client/pagefactory/utils/WebDriverUnpackUtility.java +++ b/src/main/java/io/appium/java_client/pagefactory/utils/WebDriverUnpackUtility.java @@ -16,13 +16,8 @@ package io.appium.java_client.pagefactory.utils; -import io.appium.java_client.android.AndroidDriver; -import io.appium.java_client.ios.IOSDriver; import io.appium.java_client.pagefactory.bys.ContentType; -import io.appium.java_client.remote.MobileCapabilityType; -import io.appium.java_client.remote.MobilePlatform; import org.openqa.selenium.ContextAware; -import org.openqa.selenium.HasCapabilities; import org.openqa.selenium.SearchContext; import org.openqa.selenium.WebDriver; import org.openqa.selenium.internal.WrapsDriver; @@ -70,62 +65,6 @@ public static WebDriver unpackWebDriverFromSearchContext(SearchContext searchCon return null; } - /** - * @param driver is an instance of {@link org.openqa.selenium.WebDriver}. - * @return it returns current mobile platform name. Take a look at - * {@link io.appium.java_client.remote.MobilePlatform}. - * Note: the given {@link org.openqa.selenium.WebDriver} should implement - * @link org.openqa.selenium.HasCapabilities} also. This method will return null - * otherwise. - */ - public static String getPlatform(WebDriver driver) { - if (driver == null) { - return null; - } - - Class driverClass = driver.getClass(); - if (AndroidDriver.class.isAssignableFrom(driverClass)) { - return MobilePlatform.ANDROID; - } - - if (IOSDriver.class.isAssignableFrom(driverClass)) { - return MobilePlatform.IOS; - } - - //it is possible that somebody uses RemoteWebDriver or their - //own WebDriver implementation. At this case capabilities are used - //to detect platform - if (HasCapabilities.class.isAssignableFrom(driverClass)) { - return String.valueOf(((HasCapabilities) driver).getCapabilities() - .getCapability(MobileCapabilityType.PLATFORM_NAME)); - } - - return null; - } - - /** - * - * @param driver is an instance of {@link org.openqa.selenium.WebDriver}. - * @return it returns current automation type. Take a look at - * {@link io.appium.java_client.remote.AutomationName}. - * Note: the given {@link org.openqa.selenium.WebDriver} should implement - * {@link org.openqa.selenium.HasCapabilities} also. This method will return null - * otherwise. - * - */ - public static String getAutomation(WebDriver driver) { - if (driver == null) { - return null; - } - - if (HasCapabilities.class.isAssignableFrom(driver.getClass())) { - return String.valueOf(((HasCapabilities) driver).getCapabilities() - .getCapability(MobileCapabilityType.AUTOMATION_NAME)); - } - - return null; - } - /** * @param context is an instance of {@link org.openqa.selenium.SearchContext} * It may be the instance of {@link org.openqa.selenium.WebDriver} diff --git a/src/test/java/io/appium/java_client/android/AndroidDriverTest.java b/src/test/java/io/appium/java_client/android/AndroidDriverTest.java index 02387d1d8..19c4a778c 100644 --- a/src/test/java/io/appium/java_client/android/AndroidDriverTest.java +++ b/src/test/java/io/appium/java_client/android/AndroidDriverTest.java @@ -126,12 +126,12 @@ public class AndroidDriverTest extends BaseAndroidTest { } @Test public void getDeviceUDIDTest() { - String deviceSerial = driver.getSessionDetails().get("deviceUDID").toString(); + String deviceSerial = driver.getSessionDetail("deviceUDID").toString(); assertNotNull(deviceSerial); } @Test public void getSessionMapData() { - Map map = (Map) driver.getSessionDetails().get("desired"); + Map map = (Map) driver.getSessionDetail("desired"); assertNotEquals(map.size(), 0); } } diff --git a/src/test/java/io/appium/java_client/pagefactory_tests/AndroidPageObjectTest.java b/src/test/java/io/appium/java_client/pagefactory_tests/AndroidPageObjectTest.java index d9f6f3f9d..60c0f37bc 100644 --- a/src/test/java/io/appium/java_client/pagefactory_tests/AndroidPageObjectTest.java +++ b/src/test/java/io/appium/java_client/pagefactory_tests/AndroidPageObjectTest.java @@ -16,6 +16,7 @@ package io.appium.java_client.pagefactory_tests; +import static io.appium.java_client.pagefactory.LocatorGroupStrategy.ALL_POSSIBLE; import static junit.framework.TestCase.assertNotNull; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; @@ -24,13 +25,13 @@ import io.appium.java_client.TouchableElement; import io.appium.java_client.android.AndroidDriver; import io.appium.java_client.android.AndroidElement; -import io.appium.java_client.pagefactory.AndroidFindAll; + import io.appium.java_client.pagefactory.AndroidFindBy; -import io.appium.java_client.pagefactory.AndroidFindBys; import io.appium.java_client.pagefactory.AppiumFieldDecorator; +import io.appium.java_client.pagefactory.HowToUseLocators; import io.appium.java_client.pagefactory.SelendroidFindBy; import io.appium.java_client.pagefactory.iOSFindBy; -import io.appium.java_client.pagefactory.iOSFindBys; + import io.appium.java_client.remote.MobileCapabilityType; import io.appium.java_client.service.local.AppiumDriverLocalService; import org.junit.AfterClass; @@ -57,11 +58,14 @@ public class AndroidPageObjectTest { private static AppiumDriverLocalService service; private boolean populated = false; - @FindBy(className = "android.widget.TextView") private List textVieWs; + @FindBy(className = "android.widget.TextView") + private List textVieWs; - @AndroidFindBy(className = "android.widget.TextView") private List androidTextViews; + @AndroidFindBy(className = "android.widget.TextView") + private List androidTextViews; - @iOSFindBy(uiAutomator = ".elements()[0]") private List iosTextViews; + @iOSFindBy(uiAutomator = ".elements()[0]") + private List iosTextViews; @iOSFindBy(uiAutomator = ".elements()[0]") @AndroidFindBy(className = "android.widget.TextView") private List androidOriOsTextViews; @@ -72,34 +76,36 @@ public class AndroidPageObjectTest { @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/text1\")") private List mobileElementViews; - @FindBy(className = "android.widget.TextView") private List mobiletextVieWs; + @FindBy(className = "android.widget.TextView") + private List mobiletextVieWs; @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/text1\")") private List remoteElementViews; - @AndroidFindBys({ - @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/list\")"), - @AndroidFindBy(className = "android.widget.TextView")}) private List - chainElementViews; + @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/list\")") + @AndroidFindBy(className = "android.widget.TextView") + private List chainElementViews; - @iOSFindBys({@iOSFindBy(uiAutomator = ".elements()[0]"), @iOSFindBy(xpath = "//someElement")}) + @iOSFindBy(uiAutomator = ".elements()[0]") @iOSFindBy(xpath = "//someElement") private List iosChainTextViews; - @AndroidFindBys({ - @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/content\")"), - @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/list\")"), - @AndroidFindBy(id = "android:id/text1")}) - @iOSFindBys({@iOSFindBy(uiAutomator = ".elements()[0]"), @iOSFindBy(xpath = "//someElement")}) + @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/content\")") + @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/list\")") + @AndroidFindBy(id = "android:id/text1") + @iOSFindBy(uiAutomator = ".elements()[0]") @iOSFindBy(xpath = "//someElement") private List chainAndroidOrIOSUIAutomatorViews; @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/text1\")") private List touchabletextVieWs; - @FindBy(id = "android:id/text1") private WebElement textView; + @FindBy(id = "android:id/text1") + private WebElement textView; - @AndroidFindBy(className = "android.widget.TextView") private WebElement androidTextView; + @AndroidFindBy(className = "android.widget.TextView") + private WebElement androidTextView; - @iOSFindBy(uiAutomator = ".elements()[0]") private WebElement iosTextView; + @iOSFindBy(uiAutomator = ".elements()[0]") + private WebElement iosTextView; @AndroidFindBy(className = "android.widget.TextView") @iOSFindBy(uiAutomator = ".elements()[0]") private WebElement androidOriOsTextView; @@ -110,48 +116,50 @@ public class AndroidPageObjectTest { @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/text1\")") private MobileElement mobileElementView; - @FindBy(className = "android.widget.TextView") private MobileElement mobiletextVieW; + @FindBy(className = "android.widget.TextView") + private MobileElement mobiletextVieW; @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/text1\")") private RemoteWebElement remotetextVieW; - @AndroidFindBys({ - @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/list\")"), - @AndroidFindBy(className = "android.widget.TextView")}) private WebElement chainElementView; + @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/list\")") + @AndroidFindBy(className = "android.widget.TextView") + private WebElement chainElementView; - @iOSFindBys({@iOSFindBy(uiAutomator = ".elements()[0]"), @iOSFindBy(xpath = "//someElement")}) + @iOSFindBy(uiAutomator = ".elements()[0]") @iOSFindBy(xpath = "//someElement") private WebElement iosChainTextView; - @AndroidFindBys({ - @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/content\")"), - @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/list\")"), - @AndroidFindBy(id = "android:id/text1")}) - @iOSFindBys({@iOSFindBy(uiAutomator = ".elements()[0]"), @iOSFindBy(xpath = "//someElement")}) + @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/content\")") + @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/list\")") + @AndroidFindBy(id = "android:id/text1") + @iOSFindBy(uiAutomator = ".elements()[0]") @iOSFindBy(xpath = "//someElement") private WebElement chainAndroidOrIOSUIAutomatorView; - @AndroidFindBys({ - @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/content\")"), - @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/list\")"), - @AndroidFindBy(id = "android:id/text1")}) private AndroidElement androidElementView; - - @AndroidFindBys({ - @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/content\")"), - @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/list\")"), - @AndroidFindBy(id = "android:id/text1")}) private List androidElementViews; - - @AndroidFindAll({ - @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/Fakecontent\")"), - @AndroidFindBy(id = "android:id/Faketext1"), - @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/list\")"), - //by this locator element is found - @AndroidFindBy(id = "android:id/FakeId")}) private List findAllElementViews; - - @AndroidFindAll({ - @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/Fakecontent\")"), - @AndroidFindBy(id = "android:id/Faketext1"), - @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/list\")"), - //by this locator element is found - @AndroidFindBy(id = "android:id/FakeId")}) private WebElement findAllElementView; + @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/content\")") + @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/list\")") + @AndroidFindBy(id = "android:id/text1") + private AndroidElement androidElementView; + + @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/content\")") + @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/list\")") + @AndroidFindBy(id = "android:id/text1") + private List androidElementViews; + + @HowToUseLocators(androidAutomation = ALL_POSSIBLE) + @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/Fakecontent\")") + @AndroidFindBy(id = "android:id/Faketext1") + @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/list\")") + //by this locator element is found + @AndroidFindBy(id = "android:id/FakeId") + private List findAllElementViews; + + @HowToUseLocators(androidAutomation = ALL_POSSIBLE) + @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/Fakecontent\")") + @AndroidFindBy(id = "android:id/Faketext1") + @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/list\")") + //by this locator element is found + @AndroidFindBy(id = "android:id/FakeId") + private WebElement findAllElementView; @AndroidFindBy(id = "android:id/text1") @SelendroidFindBy(id = "Invalid Identifier") private WebElement textAndroidId; @@ -159,15 +167,17 @@ public class AndroidPageObjectTest { @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/text1\")") private TouchableElement touchabletextVieW; - @iOSFindBy(uiAutomator = ".elements()[0]") @FindBy(css = "e.e1.e2") private List - elementsWhenAndroidLocatorIsNotDefinedAndThereIsInvalidFindBy; + @iOSFindBy(uiAutomator = ".elements()[0]") @FindBy(css = "e.e1.e2") + private List elementsWhenAndroidLocatorIsNotDefinedAndThereIsInvalidFindBy; - @iOSFindBy(uiAutomator = ".elements()[0]") @FindBy(css = "e.e1.e2") private WebElement - elementWhenAndroidLocatorIsNotDefinedAndThereIsInvalidFindBy; + @iOSFindBy(uiAutomator = ".elements()[0]") @FindBy(css = "e.e1.e2") + private WebElement elementWhenAndroidLocatorIsNotDefinedAndThereIsInvalidFindBy; - @FindBy(id = "fakeId") private WebElement fakeElement; + @FindBy(id = "fakeId") + private WebElement fakeElement; - @FindBy(id = "fakeId") private List fakeElements; + @FindBy(id = "fakeId") + private List fakeElements; /** * initialization. diff --git a/src/test/java/io/appium/java_client/pagefactory_tests/DesktopBrowserCompatibilityTest.java b/src/test/java/io/appium/java_client/pagefactory_tests/DesktopBrowserCompatibilityTest.java index 185a9b254..982e12595 100644 --- a/src/test/java/io/appium/java_client/pagefactory_tests/DesktopBrowserCompatibilityTest.java +++ b/src/test/java/io/appium/java_client/pagefactory_tests/DesktopBrowserCompatibilityTest.java @@ -16,14 +16,15 @@ package io.appium.java_client.pagefactory_tests; +import static io.appium.java_client.pagefactory.LocatorGroupStrategy.ALL_POSSIBLE; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import io.appium.java_client.android.AndroidDriver; import io.appium.java_client.pagefactory.AndroidFindBy; import io.appium.java_client.pagefactory.AppiumFieldDecorator; +import io.appium.java_client.pagefactory.HowToUseLocators; import io.appium.java_client.pagefactory.iOSFindBy; -import io.appium.java_client.pagefactory.iOSFindBys; import org.junit.Test; import org.openqa.selenium.Platform; import org.openqa.selenium.WebDriver; @@ -42,9 +43,11 @@ public class DesktopBrowserCompatibilityTest { private final Platform current = Platform.getCurrent(); + @HowToUseLocators(iOSAutomation = ALL_POSSIBLE) @AndroidFindBy(className = "someClass") - @iOSFindBys({@iOSFindBy(xpath = "//selector[1]"), @iOSFindBy(xpath = "//someTag")}) - @FindBys({@FindBy(id = "main"), @FindBy(tagName = "p")}) private List foundLinks; + @iOSFindBy(xpath = "//selector[1]") @iOSFindBy(xpath = "//someTag") + @FindBys({@FindBy(id = "main"), @FindBy(tagName = "p")}) + private List foundLinks; private List main; //this list is located by id="main" private WebDriver trap1; private List> trap2; diff --git a/src/test/java/io/appium/java_client/pagefactory_tests/IOSPageFactoryTest.java b/src/test/java/io/appium/java_client/pagefactory_tests/IOSPageFactoryTest.java index f670eb250..7970454b4 100644 --- a/src/test/java/io/appium/java_client/pagefactory_tests/IOSPageFactoryTest.java +++ b/src/test/java/io/appium/java_client/pagefactory_tests/IOSPageFactoryTest.java @@ -16,6 +16,7 @@ package io.appium.java_client.pagefactory_tests; +import static io.appium.java_client.pagefactory.LocatorGroupStrategy.ALL_POSSIBLE; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; @@ -26,11 +27,9 @@ import io.appium.java_client.ios.IOSElement; import io.appium.java_client.pagefactory.AndroidFindBy; -import io.appium.java_client.pagefactory.AndroidFindBys; import io.appium.java_client.pagefactory.AppiumFieldDecorator; -import io.appium.java_client.pagefactory.iOSFindAll; +import io.appium.java_client.pagefactory.HowToUseLocators; import io.appium.java_client.pagefactory.iOSFindBy; - import io.appium.java_client.remote.IOSMobileCapabilityType; import io.appium.java_client.remote.MobileCapabilityType; import io.appium.java_client.service.local.AppiumDriverLocalService; @@ -57,35 +56,44 @@ public class IOSPageFactoryTest { private static AppiumDriverLocalService service; private boolean populated = false; - @FindBy(className = "UIAButton") private List uiButtons; + @FindBy(className = "UIAButton") + private List uiButtons; - @FindBy(className = "UIAButton") private List iosUIButtons; + @FindBy(className = "UIAButton") + private List iosUIButtons; - @iOSFindBy(uiAutomator = ".elements()[0]") private List iosUIAutomatorButtons; + @iOSFindBy(uiAutomator = ".elements()[0]") + private List iosUIAutomatorButtons; - @iOSFindBy(uiAutomator = ".elements()[0]") @AndroidFindBy(className = "android.widget.TextView") + @iOSFindBy(uiAutomator = ".elements()[0]") + @AndroidFindBy(className = "android.widget.TextView") private List androidOriOsTextViews; @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/text1\")") private List androidUIAutomatorViews; - @iOSFindBy(uiAutomator = ".elements()[0]") private List mobileButtons; + @iOSFindBy(uiAutomator = ".elements()[0]") + private List mobileButtons; - @FindBy(className = "UIAButton") private List mobiletFindByButtons; + @FindBy(className = "UIAButton") + private List mobiletFindByButtons; - @iOSFindBy(uiAutomator = ".elements()[0]") private List remoteElementViews; + @iOSFindBy(uiAutomator = ".elements()[0]") + private List remoteElementViews; - @AndroidFindBys({ - @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/list\")"), - @AndroidFindBy(className = "android.widget.TextView")}) private List - chainElementViews; + @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/list\")") + @AndroidFindBy(className = "android.widget.TextView") + private List chainElementViews; - @FindBy(className = "UIAButton") private WebElement uiButton; + @FindBy(className = "UIAButton") + private WebElement uiButton; - @FindBy(className = "UIAButton") private WebElement iosUIButton; + @FindBy(className = "UIAButton") + private WebElement iosUIButton; - @iOSFindBy(uiAutomator = ".elements()[0]") private WebElement iosUIAutomatorButton; + @iOSFindBy(uiAutomator = ".elements()[0]") + private WebElement iosUIAutomatorButton; @AndroidFindBy(className = "android.widget.TextView") @iOSFindBy(uiAutomator = ".elements()[0]") private WebElement androidOriOsTextView; @@ -93,32 +101,40 @@ public class IOSPageFactoryTest { @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/text1\")") private WebElement androidUIAutomatorView; - @iOSFindBy(uiAutomator = ".elements()[0]") private MobileElement mobileButton; + @iOSFindBy(uiAutomator = ".elements()[0]") + private MobileElement mobileButton; - @iOSFindBy(uiAutomator = ".elements()[0]") private TouchableElement touchableButton; + @iOSFindBy(uiAutomator = ".elements()[0]") + private TouchableElement touchableButton; - @iOSFindBy(uiAutomator = ".elements()[0]") private List touchableButtons; + @iOSFindBy(uiAutomator = ".elements()[0]") + private List touchableButtons; - @FindBy(className = "UIAButton") private MobileElement mobiletFindByButton; + @FindBy(className = "UIAButton") + private MobileElement mobiletFindByButton; - @iOSFindBy(uiAutomator = ".elements()[0]") private RemoteWebElement remotetextVieW; + @iOSFindBy(uiAutomator = ".elements()[0]") + private RemoteWebElement remotetextVieW; - @AndroidFindBys({ - @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/list\")"), - @AndroidFindBy(className = "android.widget.TextView")}) + @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/list\")") + @AndroidFindBy(className = "android.widget.TextView") private WebElement chainElementView; - @iOSFindBy(uiAutomator = ".elements()[0]") private IOSElement iosButton; + @iOSFindBy(uiAutomator = ".elements()[0]") + private IOSElement iosButton; - @iOSFindBy(uiAutomator = ".elements()[0]") private List iosButtons; + @iOSFindBy(uiAutomator = ".elements()[0]") + private List iosButtons; - @iOSFindAll({@iOSFindBy(id = "ComputeSumButton_Test"), - @iOSFindBy(xpath = "//*[@name = \"ComputeSumButton\"]") //it is real locator - }) private WebElement findAllElement; + @HowToUseLocators(iOSAutomation = ALL_POSSIBLE) + @iOSFindBy(id = "ComputeSumButton_Test") + @iOSFindBy(xpath = "//*[@name = \"ComputeSumButton\"]") + private WebElement findAllElement; - @iOSFindAll({@iOSFindBy(id = "ComputeSumButton_Test"), - @iOSFindBy(xpath = "//*[@name = \"ComputeSumButton\"]") //it is real locator - }) private List findAllElements; + @HowToUseLocators(iOSAutomation = ALL_POSSIBLE) + @iOSFindBy(id = "ComputeSumButton_Test") + @iOSFindBy(xpath = "//*[@name = \"ComputeSumButton\"]") + private List findAllElements; @AndroidFindBy(className = "android.widget.TextView") @FindBy(css = "e.e1.e2") private List elementsWhenAndroidLocatorIsNotDefinedAndThereIsInvalidFindBy; diff --git a/src/test/java/io/appium/java_client/pagefactory_tests/MobileBrowserCompatibilityTest.java b/src/test/java/io/appium/java_client/pagefactory_tests/MobileBrowserCompatibilityTest.java index 0499b3dc4..77e466ae3 100644 --- a/src/test/java/io/appium/java_client/pagefactory_tests/MobileBrowserCompatibilityTest.java +++ b/src/test/java/io/appium/java_client/pagefactory_tests/MobileBrowserCompatibilityTest.java @@ -18,7 +18,6 @@ import io.appium.java_client.android.AndroidDriver; import io.appium.java_client.pagefactory.AndroidFindBy; -import io.appium.java_client.pagefactory.AndroidFindBys; import io.appium.java_client.pagefactory.AppiumFieldDecorator; import io.appium.java_client.remote.MobileBrowserType; import io.appium.java_client.remote.MobileCapabilityType; @@ -44,7 +43,7 @@ public class MobileBrowserCompatibilityTest { private AppiumDriverLocalService service; - @AndroidFindBys({@AndroidFindBy(className = "someClass"), @AndroidFindBy(xpath = "//someTag")}) + @AndroidFindBy(className = "someClass") @AndroidFindBy(xpath = "//someTag") private RemoteWebElement btnG; //this element should be found by id = 'btnG' or name = 'btnG' @FindBy(className = "gsfi") @@ -52,7 +51,8 @@ public class MobileBrowserCompatibilityTest { private WebElement searchTextField; @AndroidFindBy(className = "someClass") - @FindBys({@FindBy(className = "r"), @FindBy(tagName = "a")}) private List + @FindBys({@FindBy(className = "r"), @FindBy(tagName = "a")}) + private List foundLinks; /** diff --git a/src/test/java/io/appium/java_client/pagefactory_tests/SelendroidModeTest.java b/src/test/java/io/appium/java_client/pagefactory_tests/SelendroidModeTest.java index 6a79add99..707661bc3 100644 --- a/src/test/java/io/appium/java_client/pagefactory_tests/SelendroidModeTest.java +++ b/src/test/java/io/appium/java_client/pagefactory_tests/SelendroidModeTest.java @@ -16,6 +16,7 @@ package io.appium.java_client.pagefactory_tests; +import static io.appium.java_client.pagefactory.LocatorGroupStrategy.ALL_POSSIBLE; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; @@ -26,9 +27,8 @@ import io.appium.java_client.pagefactory.AndroidFindBy; import io.appium.java_client.pagefactory.AppiumFieldDecorator; -import io.appium.java_client.pagefactory.SelendroidFindAll; +import io.appium.java_client.pagefactory.HowToUseLocators; import io.appium.java_client.pagefactory.SelendroidFindBy; -import io.appium.java_client.pagefactory.SelendroidFindBys; import io.appium.java_client.remote.AndroidMobileCapabilityType; import io.appium.java_client.remote.AutomationName; import io.appium.java_client.remote.MobileCapabilityType; @@ -56,22 +56,32 @@ public class SelendroidModeTest { @SelendroidFindBy(id = "text1") private WebElement textId; - @AndroidFindBy(id = "Invalid Identifier") @SelendroidFindBy(id = "text1") private WebElement - textSelendroidId; + @AndroidFindBy(id = "Invalid Identifier") @SelendroidFindBy(id = "text1") + private WebElement textSelendroidId; - @SelendroidFindBy(name = "Accessibility") private WebElement textName; + @SelendroidFindBy(name = "Accessibility") + private WebElement textName; - @AndroidFindBy(xpath = ".//*[@name = 'Accessibility']") private WebElement textNameAndroid; + @AndroidFindBy(xpath = ".//*[@name = 'Accessibility']") + private WebElement textNameAndroid; - @FindBy(name = "Accessibility") private WebElement textNameDefault; + @FindBy(name = "Accessibility") + private WebElement textNameDefault; - @SelendroidFindBy(xpath = "//TextView[@value='Accessibility']") private WebElement textXpath; + @SelendroidFindBy(xpath = "//TextView[@value='Accessibility']") + private WebElement textXpath; - @SelendroidFindBys({@SelendroidFindBy(id = "text1")}) private WebElement textIds; + @SelendroidFindBy(id = "content") + @SelendroidFindBy(id = "text1") + private WebElement textIds; - @SelendroidFindAll({@SelendroidFindBy(id = "text1")}) private WebElement textAll; + @HowToUseLocators(selendroidAutomation = ALL_POSSIBLE) + @SelendroidFindBy(id = "text999") @SelendroidFindBy(id = "text1") + private WebElement textAll; - @SelendroidFindAll({@SelendroidFindBy(id = "text1")}) private List textsAll; + @HowToUseLocators(selendroidAutomation = ALL_POSSIBLE) + @SelendroidFindBy(id = "text999") @SelendroidFindBy(id = "text1") + private List textsAll; @SelendroidFindBy(className = "android.widget.TextView") private WebElement textClass; diff --git a/src/test/java/io/appium/java_client/pagefactory_tests/chromedriver b/src/test/java/io/appium/java_client/pagefactory_tests/chromedriver index 8c6aed5f8..2e17cecf2 100755 Binary files a/src/test/java/io/appium/java_client/pagefactory_tests/chromedriver and b/src/test/java/io/appium/java_client/pagefactory_tests/chromedriver differ diff --git a/src/test/java/io/appium/java_client/pagefactory_tests/chromedriver.exe b/src/test/java/io/appium/java_client/pagefactory_tests/chromedriver.exe index 9463a1e4b..c312e1bab 100644 Binary files a/src/test/java/io/appium/java_client/pagefactory_tests/chromedriver.exe and b/src/test/java/io/appium/java_client/pagefactory_tests/chromedriver.exe differ diff --git a/src/test/java/io/appium/java_client/pagefactory_tests/widgets/PartiallyOverrideRottenTomatoes.java b/src/test/java/io/appium/java_client/pagefactory_tests/widgets/PartiallyOverrideRottenTomatoes.java index c5ff17455..451da184d 100644 --- a/src/test/java/io/appium/java_client/pagefactory_tests/widgets/PartiallyOverrideRottenTomatoes.java +++ b/src/test/java/io/appium/java_client/pagefactory_tests/widgets/PartiallyOverrideRottenTomatoes.java @@ -3,7 +3,6 @@ import static org.junit.Assert.assertTrue; import io.appium.java_client.pagefactory.AndroidFindBy; -import io.appium.java_client.pagefactory.AndroidFindBys; import io.appium.java_client.pagefactory.OverrideWidget; import io.appium.java_client.pagefactory_tests.widgets.html.annotated.AnnotatedHtmlMovies; import io.appium.java_client.pagefactory_tests.widgets.html.annotated.AnnotatedHtmlReview; @@ -22,8 +21,8 @@ public class PartiallyOverrideRottenTomatoes implements RottenTomatoesAbstractAp private Movies simpleMovies; @FindBy(id = "main_container") - @AndroidFindBys({@AndroidFindBy(id = "android:id/content"), - @AndroidFindBy(className = "android.widget.RelativeLayout")}) + @AndroidFindBy(id = "android:id/content") + @AndroidFindBy(className = "android.widget.RelativeLayout") @OverrideWidget(html = HtmlReview.class) private Review simpleReview; diff --git a/src/test/java/io/appium/java_client/pagefactory_tests/widgets/RottenTomatoes.java b/src/test/java/io/appium/java_client/pagefactory_tests/widgets/RottenTomatoes.java index 34119aa97..d8741125d 100644 --- a/src/test/java/io/appium/java_client/pagefactory_tests/widgets/RottenTomatoes.java +++ b/src/test/java/io/appium/java_client/pagefactory_tests/widgets/RottenTomatoes.java @@ -3,7 +3,6 @@ import static org.junit.Assert.assertTrue; import io.appium.java_client.pagefactory.AndroidFindBy; -import io.appium.java_client.pagefactory.AndroidFindBys; import io.appium.java_client.pagefactory.OverrideWidget; import io.appium.java_client.pagefactory.SelendroidFindBy; import io.appium.java_client.pagefactory.iOSFindBy; @@ -46,8 +45,8 @@ public class RottenTomatoes implements RottenTomatoesAbstractApp { simpleMovies; - @AndroidFindBys({@AndroidFindBy(id = "android:id/content"), - @AndroidFindBy(className = "android.widget.RelativeLayout")}) + @AndroidFindBy(id = "android:id/content") + @AndroidFindBy(className = "android.widget.RelativeLayout") @FindBy(id = "main_container") @SelendroidFindBy(className = "android.widget.RelativeLayout") @iOSFindBy(className = "UIAWindow") diff --git a/src/test/java/io/appium/java_client/pagefactory_tests/widgets/android/RottenTomatoesApp.java b/src/test/java/io/appium/java_client/pagefactory_tests/widgets/android/RottenTomatoesApp.java index 419d4c75f..191ba6b41 100644 --- a/src/test/java/io/appium/java_client/pagefactory_tests/widgets/android/RottenTomatoesApp.java +++ b/src/test/java/io/appium/java_client/pagefactory_tests/widgets/android/RottenTomatoesApp.java @@ -3,7 +3,6 @@ import static org.junit.Assert.assertTrue; import io.appium.java_client.pagefactory.AndroidFindBy; -import io.appium.java_client.pagefactory.AndroidFindBys; import io.appium.java_client.pagefactory_tests.widgets.Movie; import io.appium.java_client.pagefactory_tests.widgets.RottenTomatoesAbstractApp; import io.appium.java_client.pagefactory_tests.widgets.android.annotated.AnnotatedAndroidMovies; @@ -23,9 +22,9 @@ public class RottenTomatoesApp implements RottenTomatoesAbstractApp { @AndroidFindBy(id = "com.codepath.example.rottentomatoes:id/lvMovies") private AndroidMovies simpleMovies; - @AndroidFindBys({@AndroidFindBy(id = "android:id/content"), - @AndroidFindBy(className = "android.widget.RelativeLayout")}) private AndroidReview - simpleReview; + @AndroidFindBy(id = "android:id/content") + @AndroidFindBy(className = "android.widget.RelativeLayout") + private AndroidReview simpleReview; private AnnotatedAndroidMovies annotatedAndroidMovies; diff --git a/src/test/java/io/appium/java_client/pagefactory_tests/widgets/android/annotated/AnnotatedAndroidReview.java b/src/test/java/io/appium/java_client/pagefactory_tests/widgets/android/annotated/AnnotatedAndroidReview.java index b68e0158e..c4d0a40b7 100644 --- a/src/test/java/io/appium/java_client/pagefactory_tests/widgets/android/annotated/AnnotatedAndroidReview.java +++ b/src/test/java/io/appium/java_client/pagefactory_tests/widgets/android/annotated/AnnotatedAndroidReview.java @@ -1,12 +1,11 @@ package io.appium.java_client.pagefactory_tests.widgets.android.annotated; import io.appium.java_client.pagefactory.AndroidFindBy; -import io.appium.java_client.pagefactory.AndroidFindBys; import io.appium.java_client.pagefactory_tests.widgets.android.simple.AndroidReview; import org.openqa.selenium.WebElement; -@AndroidFindBys({@AndroidFindBy(id = "android:id/content"), - @AndroidFindBy(className = "android.widget.RelativeLayout")}) +@AndroidFindBy(id = "android:id/content") +@AndroidFindBy(className = "android.widget.RelativeLayout") public class AnnotatedAndroidReview extends AndroidReview { protected AnnotatedAndroidReview(WebElement element) { diff --git a/src/test/java/io/appium/java_client/pagefactory_tests/widgets/android/simple/AndroidReview.java b/src/test/java/io/appium/java_client/pagefactory_tests/widgets/android/simple/AndroidReview.java index 904e3333d..c52a8dcc7 100644 --- a/src/test/java/io/appium/java_client/pagefactory_tests/widgets/android/simple/AndroidReview.java +++ b/src/test/java/io/appium/java_client/pagefactory_tests/widgets/android/simple/AndroidReview.java @@ -11,8 +11,7 @@ public class AndroidReview extends Review { @AndroidFindBy(id = "com.codepath.example.rottentomatoes:id/tvTitle") private AndroidElement title; - @AndroidFindBy(uiAutomator = - "resourceId(\"com.codepath.example.rottentomatoes:id/tvCriticsScore\")") + @AndroidFindBy(uiAutomator = "resourceId(\"com.codepath.example.rottentomatoes:id/tvCriticsScore\")") private AndroidElement score; @AndroidFindBy(id = "com.codepath.example.rottentomatoes:id/tvSynopsis") diff --git a/src/test/java/io/appium/java_client/pagefactory_tests/widgets/combined/RottenTomatoesAppWithCombinedWidgets.java b/src/test/java/io/appium/java_client/pagefactory_tests/widgets/combined/RottenTomatoesAppWithCombinedWidgets.java index 0ba2d773d..940d197c2 100644 --- a/src/test/java/io/appium/java_client/pagefactory_tests/widgets/combined/RottenTomatoesAppWithCombinedWidgets.java +++ b/src/test/java/io/appium/java_client/pagefactory_tests/widgets/combined/RottenTomatoesAppWithCombinedWidgets.java @@ -3,7 +3,6 @@ import static org.junit.Assert.assertTrue; import io.appium.java_client.pagefactory.AndroidFindBy; -import io.appium.java_client.pagefactory.AndroidFindBys; import io.appium.java_client.pagefactory.SelendroidFindBy; import io.appium.java_client.pagefactory_tests.widgets.Movie; import io.appium.java_client.pagefactory_tests.widgets.RottenTomatoesAbstractApp; @@ -26,8 +25,8 @@ public class RottenTomatoesAppWithCombinedWidgets implements RottenTomatoesAbstr @SelendroidFindBy(id = "lvMovies") @FindBy(id = "movies-collection") private CombinedMovies simpleMovies; - @AndroidFindBys({@AndroidFindBy(id = "android:id/content"), - @AndroidFindBy(className = "android.widget.RelativeLayout")}) + @AndroidFindBy(id = "android:id/content") + @AndroidFindBy(className = "android.widget.RelativeLayout") @FindBy(id = "main_container") @SelendroidFindBy(className = "android.widget.RelativeLayout") private CombinedReview simpleReview; diff --git a/src/test/java/io/appium/java_client/pagefactory_tests/widgets/combined/annotated/AnnotatedCombinedReview.java b/src/test/java/io/appium/java_client/pagefactory_tests/widgets/combined/annotated/AnnotatedCombinedReview.java index 1ddf46e03..bbc2a1bb6 100644 --- a/src/test/java/io/appium/java_client/pagefactory_tests/widgets/combined/annotated/AnnotatedCombinedReview.java +++ b/src/test/java/io/appium/java_client/pagefactory_tests/widgets/combined/annotated/AnnotatedCombinedReview.java @@ -3,7 +3,6 @@ import io.appium.java_client.pagefactory.AndroidFindBy; -import io.appium.java_client.pagefactory.AndroidFindBys; import io.appium.java_client.pagefactory.SelendroidFindBy; import io.appium.java_client.pagefactory_tests.widgets.combined.simple.CombinedReview; import org.openqa.selenium.WebElement; @@ -11,8 +10,8 @@ @FindBy(id = "main_container") @SelendroidFindBy(className = "android.widget.RelativeLayout") -@AndroidFindBys({@AndroidFindBy(id = "android:id/content"), - @AndroidFindBy(className = "android.widget.RelativeLayout")}) +@AndroidFindBy(id = "android:id/content") +@AndroidFindBy(className = "android.widget.RelativeLayout") public class AnnotatedCombinedReview extends CombinedReview { protected AnnotatedCombinedReview(WebElement element) { super(element); diff --git a/src/test/java/io/appium/java_client/pagefactory_tests/widgets/ios/simple/IOSReview.java b/src/test/java/io/appium/java_client/pagefactory_tests/widgets/ios/simple/IOSReview.java index fd18e09c6..98e5ec5ac 100644 --- a/src/test/java/io/appium/java_client/pagefactory_tests/widgets/ios/simple/IOSReview.java +++ b/src/test/java/io/appium/java_client/pagefactory_tests/widgets/ios/simple/IOSReview.java @@ -2,17 +2,16 @@ import io.appium.java_client.ios.IOSElement; import io.appium.java_client.pagefactory.iOSFindBy; -import io.appium.java_client.pagefactory.iOSFindBys; import io.appium.java_client.pagefactory_tests.widgets.Review; import org.openqa.selenium.WebElement; //className = UIAWindow public class IOSReview extends Review { - @iOSFindBys({@iOSFindBy(className = "UIANavigationBar"), - @iOSFindBy(className = "UIAStaticText")}) private IOSElement title; + @iOSFindBy(className = "UIANavigationBar") @iOSFindBy(className = "UIAStaticText") + private IOSElement title; - @iOSFindBys({@iOSFindBy(className = "UIAScrollView"), @iOSFindBy(className = "UIAStaticText")}) + @iOSFindBy(className = "UIAScrollView") @iOSFindBy(className = "UIAStaticText") private IOSElement synopsis; @iOSFindBy(className = "UIAImage") private IOSElement poster;