diff --git a/google-style.xml b/google-style.xml index dd40c8a90..6f3440428 100755 --- a/google-style.xml +++ b/google-style.xml @@ -158,7 +158,7 @@ - + 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 abd3e8773..ad07603e3 100644 --- a/src/main/java/io/appium/java_client/pagefactory/AppiumFieldDecorator.java +++ b/src/main/java/io/appium/java_client/pagefactory/AppiumFieldDecorator.java @@ -21,6 +21,8 @@ import static io.appium.java_client.pagefactory.utils.WebDriverUnpackUtility .unpackWebDriverFromSearchContext; +import com.google.common.collect.ImmutableList; + import io.appium.java_client.HasSessionDetails; import io.appium.java_client.MobileElement; import io.appium.java_client.TouchableElement; @@ -58,22 +60,9 @@ */ public class AppiumFieldDecorator implements FieldDecorator { - private static final List> availableElementClasses = - new ArrayList>() { - private static final long serialVersionUID = 1L; - - { - add(WebElement.class); - add(RemoteWebElement.class); - add(MobileElement.class); - add(TouchableElement.class); - add(AndroidElement.class); - add(IOSElement.class); - add(WindowsElement.class); - } - - }; - + private static final List> availableElementClasses = ImmutableList.of(WebElement.class, + RemoteWebElement.class, MobileElement.class, TouchableElement.class, AndroidElement.class, + IOSElement.class, WindowsElement.class); public static long DEFAULT_IMPLICITLY_WAIT_TIMEOUT = 1; public static TimeUnit DEFAULT_TIMEUNIT = TimeUnit.SECONDS; private final WebDriver originalDriver; 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 217ae2b3a..77ca9b614 100644 --- a/src/main/java/io/appium/java_client/pagefactory/DefaultElementByBuilder.java +++ b/src/main/java/io/appium/java_client/pagefactory/DefaultElementByBuilder.java @@ -176,6 +176,14 @@ private static By buildMobileBy(LocatorGroupStrategy locatorGroupStrategy, Annot } } + if (isIOSXcuit()) { + iOSXCUITFindBy[] xCuitFindByArray = annotatedElement.getAnnotationsByType(iOSXCUITFindBy.class); + if (xCuitFindByArray != null && xCuitFindByArray.length > 0) { + return buildMobileBy(howToUseLocators != null ? howToUseLocators.iOSXCUITAutomation() : null, + xCuitFindByArray); + } + } + if (isIOS()) { iOSFindBy[] iOSFindByArray = annotatedElement.getAnnotationsByType(iOSFindBy.class); //should be kept for some time diff --git a/src/main/java/io/appium/java_client/pagefactory/HowToUseLocators.java b/src/main/java/io/appium/java_client/pagefactory/HowToUseLocators.java index 5b8affe94..5208367b7 100644 --- a/src/main/java/io/appium/java_client/pagefactory/HowToUseLocators.java +++ b/src/main/java/io/appium/java_client/pagefactory/HowToUseLocators.java @@ -50,4 +50,11 @@ * or the searching by all possible locators. */ LocatorGroupStrategy windowsAutomation() default LocatorGroupStrategy.CHAIN; + + /** + * @return the strategy which defines how to use locators which are described by + * the {@link iOSXCUITFindBy} annotation. These annotations can define the chained searching + * or the searching by all possible locators. + */ + LocatorGroupStrategy iOSXCUITAutomation() default LocatorGroupStrategy.CHAIN; } diff --git a/src/main/java/io/appium/java_client/pagefactory/bys/builder/AppiumByBuilder.java b/src/main/java/io/appium/java_client/pagefactory/bys/builder/AppiumByBuilder.java index 2c4f84f99..d2b34c64e 100644 --- a/src/main/java/io/appium/java_client/pagefactory/bys/builder/AppiumByBuilder.java +++ b/src/main/java/io/appium/java_client/pagefactory/bys/builder/AppiumByBuilder.java @@ -16,6 +16,7 @@ package io.appium.java_client.pagefactory.bys.builder; +import static io.appium.java_client.remote.AutomationName.IOS_XCUI_TEST; import static io.appium.java_client.remote.AutomationName.SELENDROID; import static io.appium.java_client.remote.MobilePlatform.ANDROID; import static io.appium.java_client.remote.MobilePlatform.IOS; @@ -180,6 +181,10 @@ protected boolean isIOS() { return IOS.equalsIgnoreCase(platform); } + protected boolean isIOSXcuit() { + return isIOS() && IOS_XCUI_TEST.equalsIgnoreCase(automation); + } + protected boolean isWindows() { return WINDOWS.equalsIgnoreCase(platform); } 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 9489311d2..923779511 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 @@ -90,6 +90,12 @@ enum Strategies { return MobileBy .windowsAutomation(getValue(annotation, this)); } + }, + BY_NS_PREDICATE("iOSNsPredicate") { + @Override By getBy(Annotation annotation) { + return MobileBy + .iOSNsPredicateString(getValue(annotation, this)); + } }; private final String valueName; diff --git a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBy.java b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBy.java new file mode 100644 index 000000000..aa1910ec8 --- /dev/null +++ b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBy.java @@ -0,0 +1,62 @@ +/* + * 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.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE}) +@Repeatable(iOSXCUITFindBySet.class) +public @interface iOSXCUITFindBy { + + /** + * The NSPredicate class is used to define logical conditions used to constrain + * a search either for a fetch or for in-memory filtering. + */ + String iOSNsPredicate() default ""; + + /** + * It an UI automation accessibility Id which is a convenient to iOS. + * About iOS accessibility + * {@link "https://developer.apple.com/library/ios/documentation/UIKit/Reference/ + * UIAccessibilityIdentification_Protocol/index.html"} + */ + String accessibility() default ""; + + /** + * It is an id of the target element. + */ + String id() default ""; + + /** + * It is a name of a type/class of the target element. + */ + String className() default ""; + + /** + * It is a desired element tag. + */ + String tagName() default ""; + + /** + * It is a xpath to the target element. + */ + String xpath() default ""; +} diff --git a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBySet.java b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBySet.java new file mode 100644 index 000000000..f2f43e7b8 --- /dev/null +++ b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBySet.java @@ -0,0 +1,31 @@ +/* + * 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 iOSXCUITFindBySet { + /** + * @return an array of {@link iOSXCUITFindBy} which builds a sequence of + * the chained searching for elements or a set of possible locators + */ + iOSXCUITFindBy[] value(); +}