From 02a185232bcef357d9fa4a58e052b9ff776e0c61 Mon Sep 17 00:00:00 2001 From: Sergey Tikhomirov Date: Sun, 7 May 2017 00:21:15 +0300 Subject: [PATCH 1/9] #565: initial commit --- .../pagefactory/AndroidFindAll.java | 10 ++--- .../pagefactory/AndroidFindBy.java | 5 +++ .../pagefactory/AndroidFindBys.java | 10 ++--- .../pagefactory/SelendroidFindAll.java | 10 ++--- .../pagefactory/SelendroidFindBy.java | 5 +++ .../pagefactory/SelendroidFindBys.java | 10 ++--- .../pagefactory/WindowsFindAll.java | 42 +++++++++++++++++++ .../pagefactory/WindowsFindBy.java | 5 +++ .../pagefactory/WindowsFindBys.java | 40 ++++++++++++++++++ .../java_client/pagefactory/iOSFindAll.java | 10 ++--- .../java_client/pagefactory/iOSFindBy.java | 5 +++ .../java_client/pagefactory/iOSFindBys.java | 10 ++--- .../pagefactory/iOSXCUITFindAll.java | 42 +++++++++++++++++++ .../pagefactory/iOSXCUITFindBy.java | 5 +++ .../pagefactory/iOSXCUITFindBys.java | 40 ++++++++++++++++++ 15 files changed, 219 insertions(+), 30 deletions(-) create mode 100644 src/main/java/io/appium/java_client/pagefactory/WindowsFindAll.java create mode 100644 src/main/java/io/appium/java_client/pagefactory/WindowsFindBys.java create mode 100644 src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindAll.java create mode 100644 src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBys.java 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 3f3327ee4..e7ee50e8e 100644 --- a/src/main/java/io/appium/java_client/pagefactory/AndroidFindAll.java +++ b/src/main/java/io/appium/java_client/pagefactory/AndroidFindAll.java @@ -26,12 +26,7 @@ * 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 { /** @@ -39,4 +34,9 @@ * be used to find the target element. */ AndroidFindBy[] value(); + + /** + * @return priority of the searching + */ + int priority() default 0; } 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 501cca7c7..443f5160c 100644 --- a/src/main/java/io/appium/java_client/pagefactory/AndroidFindBy.java +++ b/src/main/java/io/appium/java_client/pagefactory/AndroidFindBy.java @@ -66,4 +66,9 @@ * It is a xpath to the target element. */ String xpath() default ""; + + /** + * @return priority of the searching + */ + int priority() default 0; } 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 692d64da2..477046a39 100644 --- a/src/main/java/io/appium/java_client/pagefactory/AndroidFindBys.java +++ b/src/main/java/io/appium/java_client/pagefactory/AndroidFindBys.java @@ -24,12 +24,7 @@ /** * 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 { /** @@ -37,4 +32,9 @@ * the chain of the searching for the target element. */ AndroidFindBy[] value(); + + /** + * @return priority of the searching + */ + int priority() default 0; } 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 b9d67dd62..aa4bce02a 100644 --- a/src/main/java/io/appium/java_client/pagefactory/SelendroidFindAll.java +++ b/src/main/java/io/appium/java_client/pagefactory/SelendroidFindAll.java @@ -26,12 +26,7 @@ * 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 { /** @@ -39,4 +34,9 @@ * may be used to find the target element. */ SelendroidFindBy[] value(); + + /** + * @return priority of the searching + */ + int priority() default 0; } 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 be0cd7a10..76dfa055e 100644 --- a/src/main/java/io/appium/java_client/pagefactory/SelendroidFindBy.java +++ b/src/main/java/io/appium/java_client/pagefactory/SelendroidFindBy.java @@ -67,4 +67,9 @@ * It is a part of the text of the desired element. */ String partialLinkText() default ""; + + /** + * @return priority of the searching + */ + int priority() default 0; } 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 b0d7d9deb..5d25e3cc2 100644 --- a/src/main/java/io/appium/java_client/pagefactory/SelendroidFindBys.java +++ b/src/main/java/io/appium/java_client/pagefactory/SelendroidFindBys.java @@ -24,12 +24,7 @@ /** * 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 { /** @@ -37,4 +32,9 @@ * build the chain of the searching for the target element. */ SelendroidFindBy[] value(); + + /** + * @return priority of the searching + */ + int priority() default 0; } diff --git a/src/main/java/io/appium/java_client/pagefactory/WindowsFindAll.java b/src/main/java/io/appium/java_client/pagefactory/WindowsFindAll.java new file mode 100644 index 000000000..7bd8dc04f --- /dev/null +++ b/src/main/java/io/appium/java_client/pagefactory/WindowsFindAll.java @@ -0,0 +1,42 @@ +/* + * 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; + +/** + * Used to mark a field on a Page/Screen Object to indicate that lookup should use a series + * of {@link WindowsFindBy} tags + * It will then search for all elements that match any criteria. Note that elements + * are not guaranteed to be in document order. + */ +@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE}) +public @interface WindowsFindAll { + /** + * It is a set of {@link WindowsFindBy} strategies which may be + * used to find the target element. + */ + WindowsFindBy[] value(); + + /** + * @return priority of the searching + */ + int priority() default 0; +} diff --git a/src/main/java/io/appium/java_client/pagefactory/WindowsFindBy.java b/src/main/java/io/appium/java_client/pagefactory/WindowsFindBy.java index 8a56f9898..167780bef 100644 --- a/src/main/java/io/appium/java_client/pagefactory/WindowsFindBy.java +++ b/src/main/java/io/appium/java_client/pagefactory/WindowsFindBy.java @@ -62,4 +62,9 @@ * It is a xpath to the target element. */ String xpath() default ""; + + /** + * @return priority of the searching + */ + int priority() default 0; } diff --git a/src/main/java/io/appium/java_client/pagefactory/WindowsFindBys.java b/src/main/java/io/appium/java_client/pagefactory/WindowsFindBys.java new file mode 100644 index 000000000..ae1c34fc4 --- /dev/null +++ b/src/main/java/io/appium/java_client/pagefactory/WindowsFindBys.java @@ -0,0 +1,40 @@ +/* + * 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; + +/** + * Used to mark a field on a Page Object to indicate that lookup should use + * a series of {@link WindowsFindBy} tags. + */ +@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE}) +public @interface WindowsFindBys { + /** + * It is a set of {@link WindowsFindBy} strategies which build + * the chain of the searching for the target element. + */ + WindowsFindBy[] value(); + + /** + * @return priority of the searching + */ + int priority() default 0; +} 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 a622a8246..059cff2e1 100644 --- a/src/main/java/io/appium/java_client/pagefactory/iOSFindAll.java +++ b/src/main/java/io/appium/java_client/pagefactory/iOSFindAll.java @@ -26,12 +26,7 @@ * 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 { /** @@ -39,4 +34,9 @@ * used to find the target element. */ iOSFindBy[] value(); + + /** + * @return priority of the searching + */ + int priority() default 0; } 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 6c193bb0a..4518e15a5 100644 --- a/src/main/java/io/appium/java_client/pagefactory/iOSFindBy.java +++ b/src/main/java/io/appium/java_client/pagefactory/iOSFindBy.java @@ -66,4 +66,9 @@ * It is a xpath to the target element. */ String xpath() default ""; + + /** + * @return priority of the searching + */ + int priority() default 0; } 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 51fb3fe68..3d034583f 100644 --- a/src/main/java/io/appium/java_client/pagefactory/iOSFindBys.java +++ b/src/main/java/io/appium/java_client/pagefactory/iOSFindBys.java @@ -24,12 +24,7 @@ /** * 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 { /** @@ -37,4 +32,9 @@ * the chain of the searching for the target element. */ iOSFindBy[] value(); + + /** + * @return priority of the searching + */ + int priority() default 0; } diff --git a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindAll.java b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindAll.java new file mode 100644 index 000000000..7b7ea9f47 --- /dev/null +++ b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindAll.java @@ -0,0 +1,42 @@ +/* + * 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; + +/** + * Used to mark a field on a Page/Screen Object to indicate that lookup should use a series + * of {@link iOSXCUITFindBy} tags + * It will then search for all elements that match any criteria. Note that elements + * are not guaranteed to be in document order. + */ +@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE}) +public @interface iOSXCUITFindAll { + /** + * It is a set of {@link iOSXCUITFindBy} strategies which may be + * used to find the target element. + */ + iOSXCUITFindBy[] value(); + + /** + * @return priority of the searching + */ + int priority() default 0; +} diff --git a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBy.java b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBy.java index 2baf2e866..1df36af94 100644 --- a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBy.java +++ b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBy.java @@ -66,4 +66,9 @@ * It is a xpath to the target element. */ String xpath() default ""; + + /** + * @return priority of the searching + */ + int priority() default 0; } diff --git a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBys.java b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBys.java new file mode 100644 index 000000000..8c2d9563a --- /dev/null +++ b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBys.java @@ -0,0 +1,40 @@ +/* + * 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; + +/** + * Used to mark a field on a Page Object to indicate that lookup should use + * a series of {@link iOSXCUITFindBy} tags. + */ +@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE}) +public @interface iOSXCUITFindBys { + /** + * It is a set of {@link iOSXCUITFindBy} strategies which build + * the chain of the searching for the target element. + */ + iOSXCUITFindBy[] value(); + + /** + * @return priority of the searching + */ + int priority() default 0; +} From d44701489326dca46543132f4f7f001f41a9bedf Mon Sep 17 00:00:00 2001 From: Sergey Tikhomirov Date: Mon, 8 May 2017 01:04:16 +0300 Subject: [PATCH 2/9] #565: Repeatable complex locators --- .../pagefactory/AndroidFindAll.java | 10 ++++++--- .../pagefactory/AndroidFindBy.java | 8 ++++--- .../pagefactory/AndroidFindByAllSet.java | 22 +++++++++++++++++++ .../pagefactory/AndroidFindByChainSet.java | 22 +++++++++++++++++++ .../pagefactory/AndroidFindBySet.java | 10 +++++---- .../pagefactory/AndroidFindBys.java | 10 ++++++--- .../pagefactory/WindowsFindAll.java | 10 ++++++--- .../pagefactory/WindowsFindBy.java | 8 ++++--- .../pagefactory/WindowsFindByAllSet.java | 22 +++++++++++++++++++ .../pagefactory/WindowsFindByChainSet.java | 22 +++++++++++++++++++ .../pagefactory/WindowsFindBySet.java | 10 +++++---- .../pagefactory/WindowsFindBys.java | 10 ++++++--- .../java_client/pagefactory/iOSFindAll.java | 10 ++++++--- .../java_client/pagefactory/iOSFindBy.java | 8 ++++--- .../pagefactory/iOSFindByAllSet.java | 22 +++++++++++++++++++ .../pagefactory/iOSFindByChainSet.java | 22 +++++++++++++++++++ .../java_client/pagefactory/iOSFindBySet.java | 10 +++++---- .../java_client/pagefactory/iOSFindBys.java | 10 ++++++--- .../pagefactory/iOSXCUITFindAll.java | 10 ++++++--- .../pagefactory/iOSXCUITFindBy.java | 8 ++++--- .../pagefactory/iOSXCUITFindByAllSet.java | 22 +++++++++++++++++++ .../pagefactory/iOSXCUITFindByChainSet.java | 22 +++++++++++++++++++ .../pagefactory/iOSXCUITFindBySet.java | 9 +++++--- .../pagefactory/iOSXCUITFindBys.java | 10 ++++++--- 24 files changed, 276 insertions(+), 51 deletions(-) create mode 100644 src/main/java/io/appium/java_client/pagefactory/AndroidFindByAllSet.java create mode 100644 src/main/java/io/appium/java_client/pagefactory/AndroidFindByChainSet.java create mode 100644 src/main/java/io/appium/java_client/pagefactory/WindowsFindByAllSet.java create mode 100644 src/main/java/io/appium/java_client/pagefactory/WindowsFindByChainSet.java create mode 100644 src/main/java/io/appium/java_client/pagefactory/iOSFindByAllSet.java create mode 100644 src/main/java/io/appium/java_client/pagefactory/iOSFindByChainSet.java create mode 100644 src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindByAllSet.java create mode 100644 src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindByChainSet.java 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 e7ee50e8e..6750a6824 100644 --- a/src/main/java/io/appium/java_client/pagefactory/AndroidFindAll.java +++ b/src/main/java/io/appium/java_client/pagefactory/AndroidFindAll.java @@ -16,18 +16,22 @@ 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; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + /** * Used to mark a field on a Page/Screen Object to indicate that lookup should use a * 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. */ -@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE}) +@Retention(RUNTIME) @Target({FIELD, TYPE}) +@Repeatable(AndroidFindByAllSet.class) public @interface AndroidFindAll { /** * It is a set of {@link io.appium.java_client.pagefactory.AndroidFindBy} strategies which may 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 443f5160c..ea45652a9 100644 --- a/src/main/java/io/appium/java_client/pagefactory/AndroidFindBy.java +++ b/src/main/java/io/appium/java_client/pagefactory/AndroidFindBy.java @@ -16,12 +16,14 @@ 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; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + /** * Used to mark a field on a Page Object to indicate an alternative mechanism for locating the @@ -30,7 +32,7 @@ * this allows users to quickly and easily create PageObjects. * using Android UI selectors, accessibility, id, name, class name, tag and xpath */ -@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE}) +@Retention(RUNTIME) @Target({FIELD, TYPE}) @Repeatable(AndroidFindBySet.class) public @interface AndroidFindBy { /** diff --git a/src/main/java/io/appium/java_client/pagefactory/AndroidFindByAllSet.java b/src/main/java/io/appium/java_client/pagefactory/AndroidFindByAllSet.java new file mode 100644 index 000000000..6f224c6de --- /dev/null +++ b/src/main/java/io/appium/java_client/pagefactory/AndroidFindByAllSet.java @@ -0,0 +1,22 @@ +package io.appium.java_client.pagefactory; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * Defines set of chained/possible locators. Each one locator + * should be defined with {@link AndroidFindAll} + */ +@Target(value = {TYPE, FIELD}) +@Retention(value = RUNTIME) +public @interface AndroidFindByAllSet { + /** + * @return an array of {@link AndroidFindAll} which builds a sequence of + * the chained searching for elements or a set of possible locators + */ + AndroidFindAll[] value(); +} diff --git a/src/main/java/io/appium/java_client/pagefactory/AndroidFindByChainSet.java b/src/main/java/io/appium/java_client/pagefactory/AndroidFindByChainSet.java new file mode 100644 index 000000000..9c0eba3da --- /dev/null +++ b/src/main/java/io/appium/java_client/pagefactory/AndroidFindByChainSet.java @@ -0,0 +1,22 @@ +package io.appium.java_client.pagefactory; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * Defines set of chained/possible locators. Each one locator + * should be defined with {@link io.appium.java_client.pagefactory.AndroidFindBys} + */ +@Target(value = {TYPE, FIELD}) +@Retention(value = RUNTIME) +public @interface AndroidFindByChainSet { + /** + * @return an array of {@link io.appium.java_client.pagefactory.AndroidFindBys} which builds a sequence of + * the chained searching for elements or a set of possible locators + */ + AndroidFindBys[] value(); +} diff --git a/src/main/java/io/appium/java_client/pagefactory/AndroidFindBySet.java b/src/main/java/io/appium/java_client/pagefactory/AndroidFindBySet.java index 863b619d0..cb9ff3b71 100644 --- a/src/main/java/io/appium/java_client/pagefactory/AndroidFindBySet.java +++ b/src/main/java/io/appium/java_client/pagefactory/AndroidFindBySet.java @@ -16,17 +16,19 @@ 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; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + /** * 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) +@Target(value = {TYPE, FIELD}) +@Retention(value = RUNTIME) public @interface AndroidFindBySet { /** * @return an array of {@link io.appium.java_client.pagefactory.AndroidFindBy} which builds a sequence of 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 477046a39..4d3dd8588 100644 --- a/src/main/java/io/appium/java_client/pagefactory/AndroidFindBys.java +++ b/src/main/java/io/appium/java_client/pagefactory/AndroidFindBys.java @@ -16,16 +16,20 @@ 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; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + /** * 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. */ -@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE}) +@Retention(RUNTIME) @Target({FIELD, TYPE}) +@Repeatable(AndroidFindByChainSet.class) public @interface AndroidFindBys { /** * It is a set of {@link io.appium.java_client.pagefactory.AndroidFindBy} strategies which build diff --git a/src/main/java/io/appium/java_client/pagefactory/WindowsFindAll.java b/src/main/java/io/appium/java_client/pagefactory/WindowsFindAll.java index 7bd8dc04f..3025e32aa 100644 --- a/src/main/java/io/appium/java_client/pagefactory/WindowsFindAll.java +++ b/src/main/java/io/appium/java_client/pagefactory/WindowsFindAll.java @@ -16,18 +16,22 @@ 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; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + /** * Used to mark a field on a Page/Screen Object to indicate that lookup should use a series * of {@link WindowsFindBy} tags * It will then search for all elements that match any criteria. Note that elements * are not guaranteed to be in document order. */ -@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE}) +@Retention(RUNTIME) @Target({FIELD, TYPE}) +@Repeatable(WindowsFindByAllSet.class) public @interface WindowsFindAll { /** * It is a set of {@link WindowsFindBy} strategies which may be diff --git a/src/main/java/io/appium/java_client/pagefactory/WindowsFindBy.java b/src/main/java/io/appium/java_client/pagefactory/WindowsFindBy.java index 167780bef..badb891a6 100644 --- a/src/main/java/io/appium/java_client/pagefactory/WindowsFindBy.java +++ b/src/main/java/io/appium/java_client/pagefactory/WindowsFindBy.java @@ -16,12 +16,14 @@ 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; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + /** * Used to mark a field on a Page Object to indicate an alternative mechanism for locating the * element or a list of elements. Used in conjunction with @@ -29,7 +31,7 @@ * this allows users to quickly and easily create PageObjects. * using Windows automation selectors, accessibility, id, name, class name, tag and xpath */ -@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE}) +@Retention(RUNTIME) @Target({FIELD, TYPE}) @Repeatable(WindowsFindBySet.class) public @interface WindowsFindBy { diff --git a/src/main/java/io/appium/java_client/pagefactory/WindowsFindByAllSet.java b/src/main/java/io/appium/java_client/pagefactory/WindowsFindByAllSet.java new file mode 100644 index 000000000..1b3344ea7 --- /dev/null +++ b/src/main/java/io/appium/java_client/pagefactory/WindowsFindByAllSet.java @@ -0,0 +1,22 @@ +package io.appium.java_client.pagefactory; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * Defines set of chained/possible locators. Each one locator + * should be defined with {@link WindowsFindAll} + */ +@Target(value = {TYPE, FIELD}) +@Retention(value = RUNTIME) +public @interface WindowsFindByAllSet { + /** + * @return an array of {@link WindowsFindAll} which builds a sequence of + * the chained searching for elements or a set of possible locators + */ + WindowsFindAll[] value(); +} diff --git a/src/main/java/io/appium/java_client/pagefactory/WindowsFindByChainSet.java b/src/main/java/io/appium/java_client/pagefactory/WindowsFindByChainSet.java new file mode 100644 index 000000000..1a9fe6297 --- /dev/null +++ b/src/main/java/io/appium/java_client/pagefactory/WindowsFindByChainSet.java @@ -0,0 +1,22 @@ +package io.appium.java_client.pagefactory; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * Defines set of chained/possible locators. Each one locator + * should be defined with {@link WindowsFindBys} + */ +@Target(value = {TYPE, FIELD}) +@Retention(value = RUNTIME) +public @interface WindowsFindByChainSet { + /** + * @return an array of {@link WindowsFindBys} which builds a sequence of + * the chained searching for elements or a set of possible locators + */ + WindowsFindBys[] value(); +} diff --git a/src/main/java/io/appium/java_client/pagefactory/WindowsFindBySet.java b/src/main/java/io/appium/java_client/pagefactory/WindowsFindBySet.java index 8512eed2b..9a8e4d07e 100644 --- a/src/main/java/io/appium/java_client/pagefactory/WindowsFindBySet.java +++ b/src/main/java/io/appium/java_client/pagefactory/WindowsFindBySet.java @@ -16,17 +16,19 @@ 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; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + /** * Defines set of chained/possible locators. Each one locator * should be defined with {@link WindowsFindBy} */ -@Target(value = {ElementType.TYPE, ElementType.FIELD}) -@Retention(value = RetentionPolicy.RUNTIME) +@Target(value = {TYPE, FIELD}) +@Retention(value = RUNTIME) public @interface WindowsFindBySet { /** * @return an array of {@link WindowsFindBy} which builds a sequence of diff --git a/src/main/java/io/appium/java_client/pagefactory/WindowsFindBys.java b/src/main/java/io/appium/java_client/pagefactory/WindowsFindBys.java index ae1c34fc4..80e5bd011 100644 --- a/src/main/java/io/appium/java_client/pagefactory/WindowsFindBys.java +++ b/src/main/java/io/appium/java_client/pagefactory/WindowsFindBys.java @@ -16,16 +16,20 @@ 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; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + /** * Used to mark a field on a Page Object to indicate that lookup should use * a series of {@link WindowsFindBy} tags. */ -@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE}) +@Retention(RUNTIME) @Target({FIELD, TYPE}) +@Repeatable(WindowsFindByChainSet.class) public @interface WindowsFindBys { /** * It is a set of {@link WindowsFindBy} strategies which build 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 059cff2e1..5f75c2289 100644 --- a/src/main/java/io/appium/java_client/pagefactory/iOSFindAll.java +++ b/src/main/java/io/appium/java_client/pagefactory/iOSFindAll.java @@ -16,18 +16,22 @@ 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; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + /** * Used to mark a field on a Page/Screen Object to indicate that lookup should use a series * 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. */ -@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE}) +@Retention(RUNTIME) @Target({FIELD, TYPE}) +@Repeatable(iOSFindByAllSet.class) public @interface iOSFindAll { /** * It is a set of {@link io.appium.java_client.pagefactory.iOSFindBy} strategies which may be 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 4518e15a5..5be144183 100644 --- a/src/main/java/io/appium/java_client/pagefactory/iOSFindBy.java +++ b/src/main/java/io/appium/java_client/pagefactory/iOSFindBy.java @@ -16,12 +16,14 @@ 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; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + /** * Used to mark a field on a Page Object to indicate an alternative mechanism for locating the @@ -30,7 +32,7 @@ * this allows users to quickly and easily create PageObjects. * using iOS UI selectors, accessibility, id, name, class name, tag and xpath */ -@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE}) +@Retention(RUNTIME) @Target({FIELD, TYPE}) @Repeatable(iOSFindBySet.class) public @interface iOSFindBy { /** diff --git a/src/main/java/io/appium/java_client/pagefactory/iOSFindByAllSet.java b/src/main/java/io/appium/java_client/pagefactory/iOSFindByAllSet.java new file mode 100644 index 000000000..903e78afd --- /dev/null +++ b/src/main/java/io/appium/java_client/pagefactory/iOSFindByAllSet.java @@ -0,0 +1,22 @@ +package io.appium.java_client.pagefactory; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * Defines set of chained/possible locators. Each one locator + * should be defined with {@link iOSFindAll} + */ +@Target(value = {TYPE, FIELD}) +@Retention(value = RUNTIME) +public @interface iOSFindByAllSet { + /** + * @return an array of {@link iOSFindAll} which builds a sequence of + * the chained searching for elements or a set of possible locators + */ + iOSFindAll[] value(); +} diff --git a/src/main/java/io/appium/java_client/pagefactory/iOSFindByChainSet.java b/src/main/java/io/appium/java_client/pagefactory/iOSFindByChainSet.java new file mode 100644 index 000000000..972a51e53 --- /dev/null +++ b/src/main/java/io/appium/java_client/pagefactory/iOSFindByChainSet.java @@ -0,0 +1,22 @@ +package io.appium.java_client.pagefactory; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * Defines set of chained/possible locators. Each one locator + * should be defined with {@link iOSFindBys} + */ +@Target(value = {TYPE, FIELD}) +@Retention(value = RUNTIME) +public @interface iOSFindByChainSet { + /** + * @return an array of {@link iOSFindBys} which builds a sequence of + * the chained searching for elements or a set of possible locators + */ + iOSFindBys[] value(); +} diff --git a/src/main/java/io/appium/java_client/pagefactory/iOSFindBySet.java b/src/main/java/io/appium/java_client/pagefactory/iOSFindBySet.java index 28fecc160..3faa4665b 100644 --- a/src/main/java/io/appium/java_client/pagefactory/iOSFindBySet.java +++ b/src/main/java/io/appium/java_client/pagefactory/iOSFindBySet.java @@ -16,17 +16,19 @@ 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; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + /** * 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) +@Target(value = {TYPE, FIELD}) +@Retention(value = RUNTIME) public @interface iOSFindBySet { /** * @return an array of {@link io.appium.java_client.pagefactory.iOSFindBy} which builds a sequence of 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 3d034583f..b40cd1064 100644 --- a/src/main/java/io/appium/java_client/pagefactory/iOSFindBys.java +++ b/src/main/java/io/appium/java_client/pagefactory/iOSFindBys.java @@ -16,16 +16,20 @@ 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; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + /** * 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. */ -@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE}) +@Retention(RUNTIME) @Target({FIELD, TYPE}) +@Repeatable(iOSFindByChainSet.class) public @interface iOSFindBys { /** * It is a set of {@link io.appium.java_client.pagefactory.iOSFindBy} strategies which build diff --git a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindAll.java b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindAll.java index 7b7ea9f47..1b8b87dbf 100644 --- a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindAll.java +++ b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindAll.java @@ -16,18 +16,22 @@ 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; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + /** * Used to mark a field on a Page/Screen Object to indicate that lookup should use a series * of {@link iOSXCUITFindBy} tags * It will then search for all elements that match any criteria. Note that elements * are not guaranteed to be in document order. */ -@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE}) +@Retention(RUNTIME) @Target({FIELD, TYPE}) +@Repeatable(iOSXCUITFindByAllSet.class) public @interface iOSXCUITFindAll { /** * It is a set of {@link iOSXCUITFindBy} strategies which may be diff --git a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBy.java b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBy.java index 1df36af94..be4e81f9b 100644 --- a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBy.java +++ b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBy.java @@ -16,13 +16,15 @@ 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}) +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@Retention(RUNTIME) @Target({FIELD, TYPE}) @Repeatable(iOSXCUITFindBySet.class) public @interface iOSXCUITFindBy { diff --git a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindByAllSet.java b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindByAllSet.java new file mode 100644 index 000000000..45506a002 --- /dev/null +++ b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindByAllSet.java @@ -0,0 +1,22 @@ +package io.appium.java_client.pagefactory; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * Defines set of chained/possible locators. Each one locator + * should be defined with {@link iOSXCUITFindAll} + */ +@Target(value = {TYPE, FIELD}) +@Retention(value = RUNTIME) +public @interface iOSXCUITFindByAllSet { + /** + * @return an array of {@link iOSXCUITFindAll} which builds a sequence of + * the chained searching for elements or a set of possible locators + */ + iOSXCUITFindAll[] value(); +} diff --git a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindByChainSet.java b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindByChainSet.java new file mode 100644 index 000000000..27a18c7bb --- /dev/null +++ b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindByChainSet.java @@ -0,0 +1,22 @@ +package io.appium.java_client.pagefactory; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * Defines set of chained/possible locators. Each one locator + * should be defined with {@link iOSXCUITFindBys} + */ +@Target(value = {TYPE, FIELD}) +@Retention(value = RUNTIME) +public @interface iOSXCUITFindByChainSet { + /** + * @return an array of {@link iOSXCUITFindBys} which builds a sequence of + * the chained searching for elements or a set of possible locators + */ + iOSXCUITFindBys[] value(); +} diff --git a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBySet.java b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBySet.java index f2f43e7b8..fb0f6c599 100644 --- a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBySet.java +++ b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBySet.java @@ -16,12 +16,15 @@ 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}) +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@Retention(RUNTIME) @Target({FIELD, TYPE}) public @interface iOSXCUITFindBySet { /** * @return an array of {@link iOSXCUITFindBy} which builds a sequence of diff --git a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBys.java b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBys.java index 8c2d9563a..32ea9d566 100644 --- a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBys.java +++ b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBys.java @@ -16,16 +16,20 @@ 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; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + /** * Used to mark a field on a Page Object to indicate that lookup should use * a series of {@link iOSXCUITFindBy} tags. */ -@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE}) +@Retention(RUNTIME) @Target({FIELD, TYPE}) +@Repeatable(iOSXCUITFindByChainSet.class) public @interface iOSXCUITFindBys { /** * It is a set of {@link iOSXCUITFindBy} strategies which build From 6c8532315c23a8196e54282b08e10135c25ca0d0 Mon Sep 17 00:00:00 2001 From: Sergey Tikhomirov Date: Sat, 13 May 2017 00:53:58 +0300 Subject: [PATCH 3/9] #565: Annotation comparator. --- .../pagefactory/DefaultElementByBuilder.java | 71 +++++++++++++------ 1 file changed, 49 insertions(+), 22 deletions(-) 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 7b8daf458..ab6bee81e 100644 --- a/src/main/java/io/appium/java_client/pagefactory/DefaultElementByBuilder.java +++ b/src/main/java/io/appium/java_client/pagefactory/DefaultElementByBuilder.java @@ -30,12 +30,20 @@ import java.lang.annotation.Annotation; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Comparator; import java.util.HashMap; import java.util.Map; import java.util.Optional; public class DefaultElementByBuilder extends AppiumByBuilder { + private static final String PRIORITY = "priority"; + private static final String VALUE = "value"; + private static final Class[] ANNOTATION_ARGUMENTS = new Class[] {}; + private static final Object[] ANNOTATION_PARAMETERS = new Object[] {}; + public DefaultElementByBuilder(String platform, String automation) { super(platform, automation); } @@ -65,28 +73,6 @@ private static By buildMobileBy(LocatorGroupStrategy locatorGroupStrategy, Annot @Override protected void assertValidAnnotations() { AnnotatedElement annotatedElement = annotatedElementContainer.getAnnotated(); - AndroidFindBy androidBy = annotatedElement.getAnnotation(AndroidFindBy.class); - AndroidFindBys androidBys = annotatedElement.getAnnotation(AndroidFindBys.class); - checkDisallowedAnnotationPairs(androidBy, androidBys); - AndroidFindAll androidFindAll = annotatedElement.getAnnotation(AndroidFindAll.class); - checkDisallowedAnnotationPairs(androidBy, androidFindAll); - checkDisallowedAnnotationPairs(androidBys, androidFindAll); - - SelendroidFindBy selendroidBy = annotatedElement.getAnnotation(SelendroidFindBy.class); - SelendroidFindBys selendroidBys = annotatedElement.getAnnotation(SelendroidFindBys.class); - checkDisallowedAnnotationPairs(selendroidBy, selendroidBys); - SelendroidFindAll selendroidFindAll = - annotatedElement.getAnnotation(SelendroidFindAll.class); - checkDisallowedAnnotationPairs(selendroidBy, selendroidFindAll); - checkDisallowedAnnotationPairs(selendroidBys, selendroidFindAll); - - iOSFindBy iOSBy = annotatedElement.getAnnotation(iOSFindBy.class); - iOSFindBys iOSBys = annotatedElement.getAnnotation(iOSFindBys.class); - checkDisallowedAnnotationPairs(iOSBy, iOSBys); - iOSFindAll iOSFindAll = annotatedElement.getAnnotation(iOSFindAll.class); - checkDisallowedAnnotationPairs(iOSBy, iOSFindAll); - checkDisallowedAnnotationPairs(iOSBys, iOSFindAll); - FindBy findBy = annotatedElement.getAnnotation(FindBy.class); FindBys findBys = annotatedElement.getAnnotation(FindBys.class); checkDisallowedAnnotationPairs(findBy, findBys); @@ -260,4 +246,45 @@ private By returnMappedBy(By byDefault, By nativeAppBy) { return returnMappedBy(defaultBy, mobileNativeBy); } + + private static class AnnotationComparator implements Comparator { + + @Override + public int compare(Annotation o1, Annotation o2) { + int priority1; + int priority2; + Method priority; + + Class c1 = o1.getClass(); + Class c2 = o2.getClass(); + + if (!c1.equals(c2)) { + throw new ClassCastException(String.format("Given annotations have different classes (%s, %s). " + + "Annotations of the same classes are required.", c1.getName(), c2.getName())); + } + + try { + priority = c1.getMethod(PRIORITY, ANNOTATION_ARGUMENTS); + } catch (NoSuchMethodException e) { + throw new ClassCastException(String.format("Class %s has no '%s' method", c1.getName(), PRIORITY)); + } + + try { + priority1 = (int) priority.invoke(o1, ANNOTATION_PARAMETERS); + priority2 = (int) priority.invoke(o2, ANNOTATION_PARAMETERS); + + if (priority2 > priority1) { + return -1; + } + else if (priority2 < priority1){ + return 1; + } + else { + return 0; + } + } catch (IllegalAccessException|InvocationTargetException e) { + throw new RuntimeException(e); + } + } + } } \ No newline at end of file From 29336b82a0987c8ee8d93e310b3f0ca81d158b7a Mon Sep 17 00:00:00 2001 From: Sergey Tikhomirov Date: Sun, 14 May 2017 01:55:00 +0300 Subject: [PATCH 4/9] #565: The feature was implemented but it needs to be covered with tests --- .../pagefactory/AndroidFindAll.java | 2 +- .../pagefactory/AndroidFindBy.java | 2 +- .../pagefactory/AndroidFindBys.java | 2 +- .../pagefactory/DefaultElementByBuilder.java | 162 ++++++++---------- .../pagefactory/SelendroidFindAll.java | 2 +- .../pagefactory/SelendroidFindBy.java | 2 +- .../pagefactory/SelendroidFindByAllSet.java | 36 ++++ .../pagefactory/SelendroidFindByChainSet.java | 36 ++++ .../pagefactory/SelendroidFindBys.java | 2 +- .../pagefactory/WindowsFindAll.java | 2 +- .../pagefactory/WindowsFindBy.java | 2 +- .../pagefactory/WindowsFindBys.java | 2 +- .../bys/builder/AppiumByBuilder.java | 4 + .../pagefactory/bys/builder/ByChained.java | 2 +- .../java_client/pagefactory/iOSFindAll.java | 2 +- .../java_client/pagefactory/iOSFindBy.java | 2 +- .../java_client/pagefactory/iOSFindBys.java | 2 +- .../pagefactory/iOSXCUITFindAll.java | 2 +- .../pagefactory/iOSXCUITFindBy.java | 2 +- .../pagefactory/iOSXCUITFindBys.java | 2 +- 20 files changed, 163 insertions(+), 107 deletions(-) create mode 100644 src/main/java/io/appium/java_client/pagefactory/SelendroidFindByAllSet.java create mode 100644 src/main/java/io/appium/java_client/pagefactory/SelendroidFindByChainSet.java 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 6750a6824..c467b533f 100644 --- a/src/main/java/io/appium/java_client/pagefactory/AndroidFindAll.java +++ b/src/main/java/io/appium/java_client/pagefactory/AndroidFindAll.java @@ -40,7 +40,7 @@ AndroidFindBy[] value(); /** - * @return priority of the searching + * @return priority of the searching. Higher number means lower priority. */ int priority() default 0; } 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 ea45652a9..4c5210691 100644 --- a/src/main/java/io/appium/java_client/pagefactory/AndroidFindBy.java +++ b/src/main/java/io/appium/java_client/pagefactory/AndroidFindBy.java @@ -70,7 +70,7 @@ String xpath() default ""; /** - * @return priority of the searching + * @return priority of the searching. Higher number means lower priority. */ int priority() default 0; } 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 4d3dd8588..62232866a 100644 --- a/src/main/java/io/appium/java_client/pagefactory/AndroidFindBys.java +++ b/src/main/java/io/appium/java_client/pagefactory/AndroidFindBys.java @@ -38,7 +38,7 @@ AndroidFindBy[] value(); /** - * @return priority of the searching + * @return priority of the searching. Higher number means lower priority. */ int priority() default 0; } 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 ab6bee81e..b828dc2e1 100644 --- a/src/main/java/io/appium/java_client/pagefactory/DefaultElementByBuilder.java +++ b/src/main/java/io/appium/java_client/pagefactory/DefaultElementByBuilder.java @@ -19,6 +19,7 @@ import io.appium.java_client.pagefactory.bys.ContentMappedBy; import io.appium.java_client.pagefactory.bys.ContentType; import io.appium.java_client.pagefactory.bys.builder.AppiumByBuilder; +import io.appium.java_client.pagefactory.bys.builder.ByChained; import io.appium.java_client.pagefactory.bys.builder.HowToUseSelectors; import org.openqa.selenium.By; import org.openqa.selenium.support.ByIdOrName; @@ -26,6 +27,7 @@ import org.openqa.selenium.support.FindAll; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBys; +import org.openqa.selenium.support.pagefactory.ByAll; import java.lang.annotation.Annotation; import java.lang.reflect.AnnotatedElement; @@ -35,7 +37,11 @@ import java.util.Comparator; import java.util.HashMap; import java.util.Map; -import java.util.Optional; + +import static java.util.Arrays.sort; +import static java.util.Optional.ofNullable; +import static org.apache.commons.lang3.ArrayUtils.add; +import static org.apache.commons.lang3.ArrayUtils.addAll; public class DefaultElementByBuilder extends AppiumByBuilder { @@ -58,17 +64,16 @@ private static void checkDisallowedAnnotationPairs(Annotation a1, Annotation a2) } } - private static By buildMobileBy(LocatorGroupStrategy locatorGroupStrategy, Annotation[] annotations) { - if (annotations.length == 1) { - return createBy(new Annotation[] {annotations[0]}, HowToUseSelectors.USE_ONE); - } else { - LocatorGroupStrategy strategy = Optional.ofNullable(locatorGroupStrategy) - .orElse(LocatorGroupStrategy.CHAIN); - if (strategy.equals(LocatorGroupStrategy.ALL_POSSIBLE)) { - return createBy(annotations, HowToUseSelectors.USE_ANY); - } - return createBy(annotations, HowToUseSelectors.BUILD_CHAINED); + private static By buildMobileBy(LocatorGroupStrategy locatorGroupStrategy, By[] bys) { + if (bys.length == 0) { + return null; } + LocatorGroupStrategy strategy = ofNullable(locatorGroupStrategy) + .orElse(LocatorGroupStrategy.CHAIN); + if (strategy.equals(LocatorGroupStrategy.ALL_POSSIBLE)) { + return new ByAll(bys); + } + return new ByChained(bys); } @Override protected void assertValidAnnotations() { @@ -105,105 +110,80 @@ private static By buildMobileBy(LocatorGroupStrategy locatorGroupStrategy, Annot return defaultBy; } - @Override protected By buildMobileNativeBy() { + private By[] getBys(Class singleLocator, Class chainedLocator, + Class allLocator) { + AnnotationComparator comparator = new AnnotationComparator(); AnnotatedElement annotatedElement = annotatedElementContainer.getAnnotated(); - HowToUseLocators howToUseLocators = annotatedElement.getAnnotation(HowToUseLocators.class); - if (isSelendroidAutomation()) { - 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 (selendroidFindByArray != null && selendroidFindByArray.length == 1) { - return createBy(new Annotation[] {selendroidFindByArray[0]}, HowToUseSelectors.USE_ONE); - } + Annotation[] annotations = annotatedElement.getAnnotationsByType(singleLocator); + annotations = addAll(annotations, annotatedElement.getAnnotationsByType(chainedLocator)); + annotations = addAll(annotations, annotatedElement.getAnnotationsByType(allLocator)); - if (selendroidFindBys != null) { - return createBy(selendroidFindBys.value(), HowToUseSelectors.BUILD_CHAINED); - } + sort(annotations, comparator); + By[] result = new By[] {}; - if (selendroidFindByAll != null) { - return createBy(selendroidFindByAll.value(), HowToUseSelectors.USE_ANY); + for (Annotation a: annotations) { + Class annotationClass = a.getClass().getInterfaces()[0]; + if (singleLocator.equals(annotationClass)) { + result = add(result, createBy(new Annotation[] {a}, HowToUseSelectors.USE_ONE)); + continue; } - /////////////////////////////////////// - //code that supposed to be supported - if (selendroidFindByArray != null && selendroidFindByArray.length > 0) { - return buildMobileBy(howToUseLocators != null ? howToUseLocators.selendroidAutomation() : null, - selendroidFindByArray); - } - } - if (isAndroid()) { - 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 (androidFindByArray != null && androidFindByArray.length == 1) { - return createBy(new Annotation[] {androidFindByArray[0]}, HowToUseSelectors.USE_ONE); + Method value; + Annotation[] set; + try { + value = annotationClass.getMethod(VALUE, ANNOTATION_ARGUMENTS); + set = (Annotation[]) value.invoke(a, ANNOTATION_PARAMETERS); + } catch (NoSuchMethodException| IllegalAccessException| InvocationTargetException e) { + throw new ClassCastException(String.format("The annotation '%s' has no convenient '%s' method which " + + "returns array of annotations", annotationClass.getName(), VALUE)); } - if (androidFindBys != null) { - return createBy(androidFindBys.value(), HowToUseSelectors.BUILD_CHAINED); + sort(set, comparator); + if (chainedLocator.equals(annotationClass)) { + result = add(result, createBy(set, HowToUseSelectors.BUILD_CHAINED)); + continue; } - if (androidFindAll != null) { - return createBy(androidFindAll.value(), HowToUseSelectors.USE_ANY); - } - /////////////////////////////////////// - //code that supposed to be supported - if (androidFindByArray != null && androidFindByArray.length > 0) { - return buildMobileBy(howToUseLocators != null ? howToUseLocators.androidAutomation() : null, - androidFindByArray); + if (allLocator.equals(annotationClass)) { + result = add(result, createBy(set, HowToUseSelectors.USE_ANY)); } } - if (isIOSXcuit()) { - iOSXCUITFindBy[] xCuitFindByArray = annotatedElement.getAnnotationsByType(iOSXCUITFindBy.class); - if (xCuitFindByArray != null && xCuitFindByArray.length > 0) { - return buildMobileBy(howToUseLocators != null ? howToUseLocators.iOSXCUITAutomation() : null, - xCuitFindByArray); - } - } + return result; + } - if (isIOS()) { - iOSFindBy[] iOSFindByArray = annotatedElement.getAnnotationsByType(iOSFindBy.class); - //should be kept for some time - iOSFindBys iOSFindBys = annotatedElement.getAnnotation(iOSFindBys.class); - iOSFindAll iOSFindAll = annotatedElement.getAnnotation(iOSFindAll.class); + @Override protected By buildMobileNativeBy() { + AnnotatedElement annotatedElement = annotatedElementContainer.getAnnotated(); + HowToUseLocators howToUseLocators = annotatedElement.getAnnotation(HowToUseLocators.class); - if (iOSFindByArray != null && iOSFindByArray.length == 1) { - return createBy(new Annotation[] {iOSFindByArray[0]}, HowToUseSelectors.USE_ONE); - } + By result = null; + if (isSelendroidAutomation()) { + result = buildMobileBy(howToUseLocators != null ? howToUseLocators.selendroidAutomation() : null, + getBys(SelendroidFindBy.class, SelendroidFindBys.class, SelendroidFindAll.class)); + } - if (iOSFindBys != null) { - return createBy(iOSFindBys.value(), HowToUseSelectors.BUILD_CHAINED); - } + if (isAndroid() && result == null) { + result = buildMobileBy(howToUseLocators != null ? howToUseLocators.androidAutomation() : null, + getBys(AndroidFindBy.class, AndroidFindBys.class, AndroidFindAll.class)); + } - if (iOSFindAll != null) { - return createBy(iOSFindAll.value(), HowToUseSelectors.USE_ANY); - } - /////////////////////////////////////// - //code that supposed to be supported - if (iOSFindByArray != null && iOSFindByArray.length > 0) { - return buildMobileBy(howToUseLocators != null ? howToUseLocators.iOSAutomation() : null, - iOSFindByArray); - } + if (isIOSXcuit() && result == null) { + result = buildMobileBy(howToUseLocators != null ? howToUseLocators.iOSXCUITAutomation() : null, + getBys(iOSXCUITFindBy.class, iOSXCUITFindBys.class, iOSXCUITFindAll.class)); } - if (isWindows()) { - WindowsFindBy[] windowsFindByArray = annotatedElement.getAnnotationsByType(WindowsFindBy.class); - if (windowsFindByArray != null && windowsFindByArray.length > 0) { - return buildMobileBy(howToUseLocators != null ? howToUseLocators.windowsAutomation() : null, - windowsFindByArray); - } + if (isIOS() && result == null) { + result = buildMobileBy(howToUseLocators != null ? howToUseLocators.iOSAutomation() : null, + getBys(iOSFindBy.class, iOSFindBys.class, iOSFindAll.class)); + } + + if (isWindows() && result == null) { + result = buildMobileBy(howToUseLocators != null ? howToUseLocators.windowsAutomation() : null, + getBys(WindowsFindBy.class, WindowsFindBys.class, WindowsFindAll.class)); } - return null; + return ofNullable(result).orElse(null); } @Override public boolean isLookupCached() { @@ -255,8 +235,8 @@ public int compare(Annotation o1, Annotation o2) { int priority2; Method priority; - Class c1 = o1.getClass(); - Class c2 = o2.getClass(); + Class c1 = o1.getClass().getInterfaces()[0]; + Class c2 = o2.getClass().getInterfaces()[0]; if (!c1.equals(c2)) { throw new ClassCastException(String.format("Given annotations have different classes (%s, %s). " + 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 aa4bce02a..5a18adc5f 100644 --- a/src/main/java/io/appium/java_client/pagefactory/SelendroidFindAll.java +++ b/src/main/java/io/appium/java_client/pagefactory/SelendroidFindAll.java @@ -36,7 +36,7 @@ SelendroidFindBy[] value(); /** - * @return priority of the searching + * @return priority of the searching. Higher number means lower priority. */ int priority() default 0; } 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 76dfa055e..3ebf0ac0b 100644 --- a/src/main/java/io/appium/java_client/pagefactory/SelendroidFindBy.java +++ b/src/main/java/io/appium/java_client/pagefactory/SelendroidFindBy.java @@ -69,7 +69,7 @@ String partialLinkText() default ""; /** - * @return priority of the searching + * @return priority of the searching. Higher number means lower priority. */ int priority() default 0; } diff --git a/src/main/java/io/appium/java_client/pagefactory/SelendroidFindByAllSet.java b/src/main/java/io/appium/java_client/pagefactory/SelendroidFindByAllSet.java new file mode 100644 index 000000000..6c8019dcc --- /dev/null +++ b/src/main/java/io/appium/java_client/pagefactory/SelendroidFindByAllSet.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 SelendroidFindAll} + */ +@Target(value = {ElementType.TYPE, ElementType.FIELD}) +@Retention(value = RetentionPolicy.RUNTIME) +public @interface SelendroidFindByAllSet { + /** + * @return an array of {@link SelendroidFindAll} which builds a sequence of + * the chained searching for elements or a set of possible locators + */ + SelendroidFindAll[] value(); +} diff --git a/src/main/java/io/appium/java_client/pagefactory/SelendroidFindByChainSet.java b/src/main/java/io/appium/java_client/pagefactory/SelendroidFindByChainSet.java new file mode 100644 index 000000000..a344e3a11 --- /dev/null +++ b/src/main/java/io/appium/java_client/pagefactory/SelendroidFindByChainSet.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 SelendroidFindBys} + */ +@Target(value = {ElementType.TYPE, ElementType.FIELD}) +@Retention(value = RetentionPolicy.RUNTIME) +public @interface SelendroidFindByChainSet { + /** + * @return an array of {@link SelendroidFindBys} which builds a sequence of + * the chained searching for elements or a set of possible locators + */ + SelendroidFindBys[] 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 5d25e3cc2..151c725ae 100644 --- a/src/main/java/io/appium/java_client/pagefactory/SelendroidFindBys.java +++ b/src/main/java/io/appium/java_client/pagefactory/SelendroidFindBys.java @@ -34,7 +34,7 @@ SelendroidFindBy[] value(); /** - * @return priority of the searching + * @return priority of the searching. Higher number means lower priority. */ int priority() default 0; } diff --git a/src/main/java/io/appium/java_client/pagefactory/WindowsFindAll.java b/src/main/java/io/appium/java_client/pagefactory/WindowsFindAll.java index 3025e32aa..d14193d14 100644 --- a/src/main/java/io/appium/java_client/pagefactory/WindowsFindAll.java +++ b/src/main/java/io/appium/java_client/pagefactory/WindowsFindAll.java @@ -40,7 +40,7 @@ WindowsFindBy[] value(); /** - * @return priority of the searching + * @return priority of the searching. Higher number means lower priority. */ int priority() default 0; } diff --git a/src/main/java/io/appium/java_client/pagefactory/WindowsFindBy.java b/src/main/java/io/appium/java_client/pagefactory/WindowsFindBy.java index badb891a6..b4f1f914e 100644 --- a/src/main/java/io/appium/java_client/pagefactory/WindowsFindBy.java +++ b/src/main/java/io/appium/java_client/pagefactory/WindowsFindBy.java @@ -66,7 +66,7 @@ String xpath() default ""; /** - * @return priority of the searching + * @return priority of the searching. Higher number means lower priority. */ int priority() default 0; } diff --git a/src/main/java/io/appium/java_client/pagefactory/WindowsFindBys.java b/src/main/java/io/appium/java_client/pagefactory/WindowsFindBys.java index 80e5bd011..2e4f5f6fc 100644 --- a/src/main/java/io/appium/java_client/pagefactory/WindowsFindBys.java +++ b/src/main/java/io/appium/java_client/pagefactory/WindowsFindBys.java @@ -38,7 +38,7 @@ WindowsFindBy[] value(); /** - * @return priority of the searching + * @return priority of the searching. Higher number means lower priority. */ int priority() default 0; } 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 452f5fedc..063a4cbde 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 @@ -92,6 +92,10 @@ private static Method[] prepareAnnotationMethods(Class ann private static String getFilledValue(Annotation mobileBy) { Method[] values = prepareAnnotationMethods(mobileBy.getClass()); for (Method value : values) { + if (!String.class.equals(value.getReturnType())) { + continue; + } + try { String strategyParameter = value.invoke(mobileBy, new Object[] {}).toString(); if (!"".equals(strategyParameter)) { diff --git a/src/main/java/io/appium/java_client/pagefactory/bys/builder/ByChained.java b/src/main/java/io/appium/java_client/pagefactory/bys/builder/ByChained.java index 60a9800d5..9b1c101ea 100644 --- a/src/main/java/io/appium/java_client/pagefactory/bys/builder/ByChained.java +++ b/src/main/java/io/appium/java_client/pagefactory/bys/builder/ByChained.java @@ -28,7 +28,7 @@ import java.util.Optional; -class ByChained extends org.openqa.selenium.support.pagefactory.ByChained { +public class ByChained extends org.openqa.selenium.support.pagefactory.ByChained { private final By[] bys; 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 5f75c2289..563e01934 100644 --- a/src/main/java/io/appium/java_client/pagefactory/iOSFindAll.java +++ b/src/main/java/io/appium/java_client/pagefactory/iOSFindAll.java @@ -40,7 +40,7 @@ iOSFindBy[] value(); /** - * @return priority of the searching + * @return priority of the searching. Higher number means lower priority. */ int priority() default 0; } 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 5be144183..cb8125aed 100644 --- a/src/main/java/io/appium/java_client/pagefactory/iOSFindBy.java +++ b/src/main/java/io/appium/java_client/pagefactory/iOSFindBy.java @@ -70,7 +70,7 @@ String xpath() default ""; /** - * @return priority of the searching + * @return priority of the searching. Higher number means lower priority. */ int priority() default 0; } 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 b40cd1064..d687e8d40 100644 --- a/src/main/java/io/appium/java_client/pagefactory/iOSFindBys.java +++ b/src/main/java/io/appium/java_client/pagefactory/iOSFindBys.java @@ -38,7 +38,7 @@ iOSFindBy[] value(); /** - * @return priority of the searching + * @return priority of the searching. Higher number means lower priority. */ int priority() default 0; } diff --git a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindAll.java b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindAll.java index 1b8b87dbf..e8f378499 100644 --- a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindAll.java +++ b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindAll.java @@ -40,7 +40,7 @@ iOSXCUITFindBy[] value(); /** - * @return priority of the searching + * @return priority of the searching. Higher number means lower priority. */ int priority() default 0; } diff --git a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBy.java b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBy.java index be4e81f9b..f39499224 100644 --- a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBy.java +++ b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBy.java @@ -70,7 +70,7 @@ String xpath() default ""; /** - * @return priority of the searching + * @return priority of the searching. Higher number means lower priority. */ int priority() default 0; } diff --git a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBys.java b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBys.java index 32ea9d566..d8fba94a2 100644 --- a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBys.java +++ b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBys.java @@ -38,7 +38,7 @@ iOSXCUITFindBy[] value(); /** - * @return priority of the searching + * @return priority of the searching. Higher number means lower priority. */ int priority() default 0; } From 69ab3153896e0050c1617b826f0ab9a6b59b9941 Mon Sep 17 00:00:00 2001 From: Sergey Tikhomirov Date: Sat, 20 May 2017 01:36:24 +0300 Subject: [PATCH 5/9] #565: The feature was completed - bug fixes - test coverage --- .../java_client/pagefactory/AndroidBy.java | 61 +++++++++++++ .../pagefactory/AndroidFindAll.java | 6 +- .../pagefactory/AndroidFindBys.java | 6 +- .../pagefactory/DefaultElementByBuilder.java | 49 +++++----- .../java_client/pagefactory/SelendroidBy.java | 63 +++++++++++++ .../pagefactory/SelendroidFindAll.java | 6 +- .../pagefactory/SelendroidFindBys.java | 6 +- .../java_client/pagefactory/WindowsBy.java | 58 ++++++++++++ .../pagefactory/WindowsFindAll.java | 6 +- .../pagefactory/WindowsFindBys.java | 6 +- .../pagefactory/bys/builder/Strategies.java | 8 +- .../appium/java_client/pagefactory/iOSBy.java | 62 +++++++++++++ .../java_client/pagefactory/iOSFindAll.java | 6 +- .../java_client/pagefactory/iOSFindBys.java | 6 +- .../java_client/pagefactory/iOSXCUITBy.java | 69 ++++++++++++++ .../pagefactory/iOSXCUITFindAll.java | 6 +- .../pagefactory/iOSXCUITFindBys.java | 6 +- .../AndroidPageObjectTest.java | 90 +++++++++++++++++-- 18 files changed, 459 insertions(+), 61 deletions(-) create mode 100644 src/main/java/io/appium/java_client/pagefactory/AndroidBy.java create mode 100644 src/main/java/io/appium/java_client/pagefactory/SelendroidBy.java create mode 100644 src/main/java/io/appium/java_client/pagefactory/WindowsBy.java create mode 100644 src/main/java/io/appium/java_client/pagefactory/iOSBy.java create mode 100644 src/main/java/io/appium/java_client/pagefactory/iOSXCUITBy.java diff --git a/src/main/java/io/appium/java_client/pagefactory/AndroidBy.java b/src/main/java/io/appium/java_client/pagefactory/AndroidBy.java new file mode 100644 index 000000000..187316b0c --- /dev/null +++ b/src/main/java/io/appium/java_client/pagefactory/AndroidBy.java @@ -0,0 +1,61 @@ +/* + * 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; + +/** + * Used to build a complex android automator locator + */ +public @interface AndroidBy { + /** + * It is an is Android UIAutomator string. + * Read http://developer.android.com/intl/ru/tools/testing-support-library/ + * index.html#uia-apis + */ + String uiAutomator() default ""; + + /** + * It an UI automation accessibility Id which is a convenient to Android. + * About Android accessibility + * https://developer.android.com/intl/ru/training/accessibility/accessible-app.html + */ + String accessibility() default ""; + + /** + * It is an id of the target element. + */ + String id() default ""; + + /** + * It is a className 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 ""; + + /** + * @return priority of the searching. Higher number means lower priority. + */ + int priority() default 0; +} 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 c467b533f..522e8a213 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,7 @@ /** * Used to mark a field on a Page/Screen Object to indicate that lookup should use a - * series of {@link io.appium.java_client.pagefactory.AndroidFindBy} tags + * series of {@link io.appium.java_client.pagefactory.AndroidBy} tags * It will then search for all elements that match any criteria. Note that elements * are not guaranteed to be in document order. */ @@ -34,10 +34,10 @@ @Repeatable(AndroidFindByAllSet.class) public @interface AndroidFindAll { /** - * It is a set of {@link io.appium.java_client.pagefactory.AndroidFindBy} strategies which may + * It is a set of {@link io.appium.java_client.pagefactory.AndroidBy} strategies which may * be used to find the target element. */ - AndroidFindBy[] value(); + AndroidBy[] value(); /** * @return priority of the searching. Higher number means lower priority. 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 62232866a..0bbb06bea 100644 --- a/src/main/java/io/appium/java_client/pagefactory/AndroidFindBys.java +++ b/src/main/java/io/appium/java_client/pagefactory/AndroidFindBys.java @@ -26,16 +26,16 @@ /** * 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. + * a series of {@link io.appium.java_client.pagefactory.AndroidBy} tags. */ @Retention(RUNTIME) @Target({FIELD, TYPE}) @Repeatable(AndroidFindByChainSet.class) public @interface AndroidFindBys { /** - * It is a set of {@link io.appium.java_client.pagefactory.AndroidFindBy} strategies which build + * It is a set of {@link io.appium.java_client.pagefactory.AndroidBy} strategies which build * the chain of the searching for the target element. */ - AndroidFindBy[] value(); + AndroidBy[] value(); /** * @return priority of the searching. Higher number means lower priority. 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 b828dc2e1..bed1058e4 100644 --- a/src/main/java/io/appium/java_client/pagefactory/DefaultElementByBuilder.java +++ b/src/main/java/io/appium/java_client/pagefactory/DefaultElementByBuilder.java @@ -34,14 +34,12 @@ import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.util.Comparator; -import java.util.HashMap; -import java.util.Map; +import java.util.*; +import static java.util.Arrays.asList; import static java.util.Arrays.sort; import static java.util.Optional.ofNullable; import static org.apache.commons.lang3.ArrayUtils.add; -import static org.apache.commons.lang3.ArrayUtils.addAll; public class DefaultElementByBuilder extends AppiumByBuilder { @@ -115,15 +113,16 @@ private By[] getBys(Class singleLocator, Class annotations = new ArrayList<>(asList(annotatedElement.getAnnotationsByType(singleLocator))); + annotations.addAll(asList(annotatedElement.getAnnotationsByType(chainedLocator))); + annotations.addAll(asList(annotatedElement.getAnnotationsByType(allLocator))); - sort(annotations, comparator); + Annotation[] annotationsArray = annotations.toArray(new Annotation[]{}); + sort(annotationsArray, comparator); By[] result = new By[] {}; - for (Annotation a: annotations) { - Class annotationClass = a.getClass().getInterfaces()[0]; + for (Annotation a: annotationsArray) { + Class annotationClass = a.annotationType(); if (singleLocator.equals(annotationClass)) { result = add(result, createBy(new Annotation[] {a}, HowToUseSelectors.USE_ONE)); continue; @@ -231,32 +230,34 @@ private static class AnnotationComparator implements Comparator { @Override public int compare(Annotation o1, Annotation o2) { - int priority1; - int priority2; - Method priority; + int p1; + int p2; + Method priority1; + Method priority2; - Class c1 = o1.getClass().getInterfaces()[0]; - Class c2 = o2.getClass().getInterfaces()[0]; + Class c1 = o1.annotationType(); + Class c2 = o2.annotationType(); - if (!c1.equals(c2)) { - throw new ClassCastException(String.format("Given annotations have different classes (%s, %s). " + - "Annotations of the same classes are required.", c1.getName(), c2.getName())); + try { + priority1 = c1.getMethod(PRIORITY, ANNOTATION_ARGUMENTS); + } catch (NoSuchMethodException e) { + throw new ClassCastException(String.format("Class %s has no '%s' method", c1.getName(), PRIORITY)); } try { - priority = c1.getMethod(PRIORITY, ANNOTATION_ARGUMENTS); + priority2 = c2.getMethod(PRIORITY, ANNOTATION_ARGUMENTS); } catch (NoSuchMethodException e) { - throw new ClassCastException(String.format("Class %s has no '%s' method", c1.getName(), PRIORITY)); + throw new ClassCastException(String.format("Class %s has no '%s' method", c2.getName(), PRIORITY)); } try { - priority1 = (int) priority.invoke(o1, ANNOTATION_PARAMETERS); - priority2 = (int) priority.invoke(o2, ANNOTATION_PARAMETERS); + p1 = (int) priority1.invoke(o1, ANNOTATION_PARAMETERS); + p2 = (int) priority2.invoke(o2, ANNOTATION_PARAMETERS); - if (priority2 > priority1) { + if (p2 > p1) { return -1; } - else if (priority2 < priority1){ + else if (p2 < p1){ return 1; } else { diff --git a/src/main/java/io/appium/java_client/pagefactory/SelendroidBy.java b/src/main/java/io/appium/java_client/pagefactory/SelendroidBy.java new file mode 100644 index 000000000..61437c2d9 --- /dev/null +++ b/src/main/java/io/appium/java_client/pagefactory/SelendroidBy.java @@ -0,0 +1,63 @@ +/* + * 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; + + +/** + * Used to build a complex selendroid locator + */ +public @interface SelendroidBy { + /** + * It is an id of the target element. + */ + String id() default ""; + + /** + * It is used in Selendroid mode instead of accessibility id. + */ + String name() default ""; + + /** + * It is a className 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 ""; + + /** + * It is a text of the desired element. + */ + String linkText() default ""; + + /** + * It is a part of the text of the desired element. + */ + String partialLinkText() default ""; + + /** + * @return priority of the searching. Higher number means lower priority. + */ + int priority() default 0; +} 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 5a18adc5f..5e1352f56 100644 --- a/src/main/java/io/appium/java_client/pagefactory/SelendroidFindAll.java +++ b/src/main/java/io/appium/java_client/pagefactory/SelendroidFindAll.java @@ -23,17 +23,17 @@ /** * Used to mark a field on a Page/Screen Object to indicate that lookup should use a - * series of {@link io.appium.java_client.pagefactory.SelendroidFindBy} tags + * series of {@link io.appium.java_client.pagefactory.SelendroidBy} tags * It will then search for all elements that match any criteria. Note that elements * are not guaranteed to be in document order. */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE}) public @interface SelendroidFindAll { /** - * It is a set of {@link io.appium.java_client.pagefactory.SelendroidFindBy} strategies which + * It is a set of {@link io.appium.java_client.pagefactory.SelendroidBy} strategies which * may be used to find the target element. */ - SelendroidFindBy[] value(); + SelendroidBy[] value(); /** * @return priority of the searching. Higher number means lower priority. 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 151c725ae..6a3fea463 100644 --- a/src/main/java/io/appium/java_client/pagefactory/SelendroidFindBys.java +++ b/src/main/java/io/appium/java_client/pagefactory/SelendroidFindBys.java @@ -23,15 +23,15 @@ /** * 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. + * use a series of {@link io.appium.java_client.pagefactory.SelendroidBy} tags. */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE}) public @interface SelendroidFindBys { /** - * It is a set of {@link io.appium.java_client.pagefactory.SelendroidFindBy} strategies which + * It is a set of {@link io.appium.java_client.pagefactory.SelendroidBy} strategies which * build the chain of the searching for the target element. */ - SelendroidFindBy[] value(); + SelendroidBy[] value(); /** * @return priority of the searching. Higher number means lower priority. diff --git a/src/main/java/io/appium/java_client/pagefactory/WindowsBy.java b/src/main/java/io/appium/java_client/pagefactory/WindowsBy.java new file mode 100644 index 000000000..804fd86a8 --- /dev/null +++ b/src/main/java/io/appium/java_client/pagefactory/WindowsBy.java @@ -0,0 +1,58 @@ +/* + * 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; + +/** + * Used to build a complex Windows automation locator + */ +public @interface WindowsBy { + + /** + * It is an is Windows automator string. + */ + String windowsAutomation() default ""; + + /** + * It an UI automation accessibility Id which is a convenient to Windows. + */ + String accessibility() default ""; + + /** + * It is an id of the target element. + */ + String id() default ""; + + /** + * It is a className 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 ""; + + /** + * @return priority of the searching. Higher number means lower priority. + */ + int priority() default 0; +} diff --git a/src/main/java/io/appium/java_client/pagefactory/WindowsFindAll.java b/src/main/java/io/appium/java_client/pagefactory/WindowsFindAll.java index d14193d14..6ff37fc39 100644 --- a/src/main/java/io/appium/java_client/pagefactory/WindowsFindAll.java +++ b/src/main/java/io/appium/java_client/pagefactory/WindowsFindAll.java @@ -26,7 +26,7 @@ /** * Used to mark a field on a Page/Screen Object to indicate that lookup should use a series - * of {@link WindowsFindBy} tags + * of {@link WindowsBy} tags * It will then search for all elements that match any criteria. Note that elements * are not guaranteed to be in document order. */ @@ -34,10 +34,10 @@ @Repeatable(WindowsFindByAllSet.class) public @interface WindowsFindAll { /** - * It is a set of {@link WindowsFindBy} strategies which may be + * It is a set of {@link WindowsBy} strategies which may be * used to find the target element. */ - WindowsFindBy[] value(); + WindowsBy[] value(); /** * @return priority of the searching. Higher number means lower priority. diff --git a/src/main/java/io/appium/java_client/pagefactory/WindowsFindBys.java b/src/main/java/io/appium/java_client/pagefactory/WindowsFindBys.java index 2e4f5f6fc..59e5f02c3 100644 --- a/src/main/java/io/appium/java_client/pagefactory/WindowsFindBys.java +++ b/src/main/java/io/appium/java_client/pagefactory/WindowsFindBys.java @@ -26,16 +26,16 @@ /** * Used to mark a field on a Page Object to indicate that lookup should use - * a series of {@link WindowsFindBy} tags. + * a series of {@link WindowsBy} tags. */ @Retention(RUNTIME) @Target({FIELD, TYPE}) @Repeatable(WindowsFindByChainSet.class) public @interface WindowsFindBys { /** - * It is a set of {@link WindowsFindBy} strategies which build + * It is a set of {@link WindowsBy} strategies which build * the chain of the searching for the target element. */ - WindowsFindBy[] value(); + WindowsBy[] value(); /** * @return priority of the searching. Higher number means lower priority. 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 3f3961578..35fbfd6e9 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 @@ -17,7 +17,9 @@ package io.appium.java_client.pagefactory.bys.builder; import io.appium.java_client.MobileBy; +import io.appium.java_client.pagefactory.AndroidBy; import io.appium.java_client.pagefactory.AndroidFindBy; +import io.appium.java_client.pagefactory.iOSBy; import io.appium.java_client.pagefactory.iOSFindBy; import org.openqa.selenium.By; @@ -31,10 +33,12 @@ enum Strategies { BYUIAUTOMATOR("uiAutomator") { @Override By getBy(Annotation annotation) { String value = getValue(annotation, this); - if (annotation.annotationType().equals(AndroidFindBy.class)) { + if (annotation.annotationType().equals(AndroidFindBy.class) + || annotation.annotationType().equals(AndroidBy.class)) { return MobileBy.AndroidUIAutomator(value); } - if (annotation.annotationType().equals(iOSFindBy.class)) { + if (annotation.annotationType().equals(iOSFindBy.class) + || annotation.annotationType().equals(iOSBy.class)) { return MobileBy.IosUIAutomation(value); } return super.getBy(annotation); diff --git a/src/main/java/io/appium/java_client/pagefactory/iOSBy.java b/src/main/java/io/appium/java_client/pagefactory/iOSBy.java new file mode 100644 index 000000000..9a8515d6a --- /dev/null +++ b/src/main/java/io/appium/java_client/pagefactory/iOSBy.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; + + +/** + * Used to build a complex iOS automation locator + */ +public @interface iOSBy { + /** + * It is is iOS UIAutomation string. + * Read https://developer.apple.com/library/tvos/documentation/DeveloperTools/ + * Conceptual/InstrumentsUserGuide/UIAutomation.html + */ + String uiAutomator() default ""; + + /** + * It an UI automation accessibility Id which is a convenient to iOS. + * About iOS accessibility + * See UIAccessibilityIdentification + */ + 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 ""; + + /** + * @return priority of the searching. Higher number means lower priority. + */ + int priority() default 0; +} 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 563e01934..9e03d7714 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,7 @@ /** * Used to mark a field on a Page/Screen Object to indicate that lookup should use a series - * of {@link io.appium.java_client.pagefactory.iOSFindBy} tags + * of {@link io.appium.java_client.pagefactory.iOSBy} tags * It will then search for all elements that match any criteria. Note that elements * are not guaranteed to be in document order. */ @@ -34,10 +34,10 @@ @Repeatable(iOSFindByAllSet.class) public @interface iOSFindAll { /** - * It is a set of {@link io.appium.java_client.pagefactory.iOSFindBy} strategies which may be + * It is a set of {@link io.appium.java_client.pagefactory.iOSBy} strategies which may be * used to find the target element. */ - iOSFindBy[] value(); + iOSBy[] value(); /** * @return priority of the searching. Higher number means lower priority. 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 d687e8d40..172f16992 100644 --- a/src/main/java/io/appium/java_client/pagefactory/iOSFindBys.java +++ b/src/main/java/io/appium/java_client/pagefactory/iOSFindBys.java @@ -26,16 +26,16 @@ /** * 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. + * a series of {@link io.appium.java_client.pagefactory.iOSBy} tags. */ @Retention(RUNTIME) @Target({FIELD, TYPE}) @Repeatable(iOSFindByChainSet.class) public @interface iOSFindBys { /** - * It is a set of {@link io.appium.java_client.pagefactory.iOSFindBy} strategies which build + * It is a set of {@link io.appium.java_client.pagefactory.iOSBy} strategies which build * the chain of the searching for the target element. */ - iOSFindBy[] value(); + iOSBy[] value(); /** * @return priority of the searching. Higher number means lower priority. diff --git a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITBy.java b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITBy.java new file mode 100644 index 000000000..da0e44277 --- /dev/null +++ b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITBy.java @@ -0,0 +1,69 @@ +/* + * 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; + +/** + * Used to build a complex iOS XCUIT mode locator + */ +public @interface iOSXCUITBy { + + /** + * The Class Chain locator is similar to xpath, but it's faster and can only + * search direct children elements. See the + * + * documentation for more details. + */ + String iOSClassChain() default ""; + + /** + * 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 + * See UIAccessibilityIdentification + */ + 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 ""; + + /** + * @return priority of the searching. Higher number means lower priority. + */ + int priority() default 0; +} diff --git a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindAll.java b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindAll.java index e8f378499..71b065089 100644 --- a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindAll.java +++ b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindAll.java @@ -26,7 +26,7 @@ /** * Used to mark a field on a Page/Screen Object to indicate that lookup should use a series - * of {@link iOSXCUITFindBy} tags + * of {@link iOSXCUITBy} tags * It will then search for all elements that match any criteria. Note that elements * are not guaranteed to be in document order. */ @@ -34,10 +34,10 @@ @Repeatable(iOSXCUITFindByAllSet.class) public @interface iOSXCUITFindAll { /** - * It is a set of {@link iOSXCUITFindBy} strategies which may be + * It is a set of {@link iOSXCUITBy} strategies which may be * used to find the target element. */ - iOSXCUITFindBy[] value(); + iOSXCUITBy[] value(); /** * @return priority of the searching. Higher number means lower priority. diff --git a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBys.java b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBys.java index d8fba94a2..847ec2b3f 100644 --- a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBys.java +++ b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBys.java @@ -26,16 +26,16 @@ /** * Used to mark a field on a Page Object to indicate that lookup should use - * a series of {@link iOSXCUITFindBy} tags. + * a series of {@link iOSXCUITBy} tags. */ @Retention(RUNTIME) @Target({FIELD, TYPE}) @Repeatable(iOSXCUITFindByChainSet.class) public @interface iOSXCUITFindBys { /** - * It is a set of {@link iOSXCUITFindBy} strategies which build + * It is a set of {@link iOSXCUITBy} strategies which build * the chain of the searching for the target element. */ - iOSXCUITFindBy[] value(); + iOSXCUITBy[] value(); /** * @return priority of the searching. Higher number means lower priority. 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 b725c1590..9bd6f9b81 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 @@ -25,11 +25,7 @@ import io.appium.java_client.android.AndroidElement; import io.appium.java_client.android.BaseAndroidTest; -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.SelendroidFindBy; -import io.appium.java_client.pagefactory.iOSFindBy; +import io.appium.java_client.pagefactory.*; import org.junit.Before; import org.junit.Test; @@ -180,6 +176,66 @@ public class AndroidPageObjectTest extends BaseAndroidTest { @AndroidFindBy(id = "android:id/text1") private List elementsFoundByInvalidChainedSelector; + @AndroidFindBy(id = "android:id/text1", priority = 2) + @AndroidFindAll(value = { + @AndroidBy(uiAutomator = "new UiSelector().resourceId(\"android:id/list\")"), + @AndroidBy(id = "android:id/fakeId") + }, priority = 1) + @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/content\")") + private AndroidElement androidElementViewFoundByMixedSearching; + + @AndroidFindBy(id = "android:id/text1", priority = 2) + @AndroidFindAll(value = { + @AndroidBy(uiAutomator = "new UiSelector().resourceId(\"android:id/list\")"), + @AndroidBy(id = "android:id/fakeId") + }, priority = 1) + @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/content\")") + private List androidElementsViewFoundByMixedSearching; + + @AndroidFindBys({ + @AndroidBy(uiAutomator = "new UiSelector().resourceId(\"android:id/content\")", priority = 1), + @AndroidBy(className = "android.widget.FrameLayout"), + }) + @AndroidFindBys({ + @AndroidBy(id = "android:id/text1", priority = 1), + @AndroidBy(uiAutomator = "new UiSelector().resourceId(\"android:id/list\")")}) + private AndroidElement androidElementViewFoundByMixedSearching2; + + @AndroidFindBys({ + @AndroidBy(uiAutomator = "new UiSelector().resourceId(\"android:id/content\")", priority = 1), + @AndroidBy(className = "android.widget.FrameLayout"), + }) + @AndroidFindBys({ + @AndroidBy(id = "android:id/text1", priority = 1), + @AndroidBy(uiAutomator = "new UiSelector().resourceId(\"android:id/list\")")}) + private List androidElementsViewFoundByMixedSearching2; + + @HowToUseLocators(androidAutomation = ALL_POSSIBLE) + @AndroidFindBy(id = "android:id/fakeId1") + @AndroidFindBy(id = "android:id/fakeId2", priority = 1) + @AndroidFindBys(value = { + @AndroidBy(uiAutomator = "new UiSelector().resourceId(\"android:id/content\")", priority = 1), + @AndroidBy(id = "android:id/text1", priority = 3), + @AndroidBy(uiAutomator = "new UiSelector().resourceId(\"android:id/list\")", priority = 2), + @AndroidBy(className = "android.widget.FrameLayout"), + }, priority = 2) + @AndroidFindBy(id = "android:id/fakeId3", priority = 3) + @AndroidFindBy(id = "android:id/fakeId4", priority = 4) + private AndroidElement androidElementViewFoundByMixedSearching3; + + @HowToUseLocators(androidAutomation = ALL_POSSIBLE) + @AndroidFindBy(id = "android:id/fakeId1") + @AndroidFindBy(id = "android:id/fakeId2", priority = 1) + @AndroidFindBys(value = { + @AndroidBy(uiAutomator = "new UiSelector().resourceId(\"android:id/content\")", priority = 1), + @AndroidBy(id = "android:id/text1", priority = 3), + @AndroidBy(uiAutomator = "new UiSelector().resourceId(\"android:id/list\")", priority = 2), + @AndroidBy(className = "android.widget.FrameLayout"), + }, priority = 2) + @AndroidFindBy(id = "android:id/fakeId3", priority = 3) + @AndroidFindBy(id = "android:id/fakeId4", priority = 4) + private List androidElementsViewFoundByMixedSearching3; + /** * The setting up. */ @@ -333,4 +389,28 @@ public void checkThatElementSearchingThrowsExpectedExceptionIfChainedLocatorIsIn @Test public void checkThatListSearchingWorksIfChainedLocatorIsInvalid() { assertEquals(0, elementsFoundByInvalidChainedSelector.size()); } + + @Test public void checkMixedElementSearching1() { + assertNotNull(androidElementViewFoundByMixedSearching.getAttribute("text")); + } + + @Test public void checkMixedElementsSearching1() { + assertNotEquals(0, androidElementsViewFoundByMixedSearching.size()); + } + + @Test public void checkMixedElementSearching2() { + assertNotNull(androidElementViewFoundByMixedSearching2.getAttribute("text")); + } + + @Test public void checkMixedElementsSearching2() { + assertNotEquals(0, androidElementsViewFoundByMixedSearching2.size()); + } + + @Test public void checkMixedElementSearching3() { + assertNotNull(androidElementViewFoundByMixedSearching3.getAttribute("text")); + } + + @Test public void checkMixedElementsSearching3() { + assertNotEquals(0, androidElementsViewFoundByMixedSearching3.size()); + } } From 8472b4f09660151d6fdd475c9d716b6240cd39b1 Mon Sep 17 00:00:00 2001 From: Sergey Tikhomirov Date: Sun, 21 May 2017 01:03:00 +0300 Subject: [PATCH 6/9] #565: Code style issues were fixed. --- google-style.xml | 2 +- .../appium/java_client/ScreenshotState.java | 4 +-- .../java_client/pagefactory/AndroidBy.java | 2 +- .../pagefactory/AndroidFindAll.java | 8 ++--- .../pagefactory/AndroidFindBy.java | 8 ++--- .../pagefactory/AndroidFindByAllSet.java | 6 ++-- .../pagefactory/AndroidFindByChainSet.java | 6 ++-- .../pagefactory/AndroidFindBySet.java | 6 ++-- .../pagefactory/AndroidFindBys.java | 8 ++--- .../pagefactory/DefaultElementByBuilder.java | 30 ++++++++++--------- .../java_client/pagefactory/SelendroidBy.java | 2 +- .../pagefactory/SelendroidFindAll.java | 8 +++-- .../pagefactory/SelendroidFindBy.java | 8 +++-- .../pagefactory/SelendroidFindByAllSet.java | 10 ++++--- .../pagefactory/SelendroidFindByChainSet.java | 10 ++++--- .../pagefactory/SelendroidFindBySet.java | 10 ++++--- .../pagefactory/SelendroidFindBys.java | 8 +++-- .../java_client/pagefactory/WindowsBy.java | 2 +- .../pagefactory/WindowsFindAll.java | 8 ++--- .../pagefactory/WindowsFindBy.java | 8 ++--- .../pagefactory/WindowsFindByAllSet.java | 6 ++-- .../pagefactory/WindowsFindByChainSet.java | 6 ++-- .../pagefactory/WindowsFindBySet.java | 6 ++-- .../pagefactory/WindowsFindBys.java | 8 ++--- .../pagefactory/bys/builder/ByChained.java | 3 ++ .../appium/java_client/pagefactory/iOSBy.java | 2 +- .../java_client/pagefactory/iOSFindAll.java | 8 ++--- .../java_client/pagefactory/iOSFindBy.java | 8 ++--- .../pagefactory/iOSFindByAllSet.java | 10 +++---- .../pagefactory/iOSFindByChainSet.java | 10 +++---- .../java_client/pagefactory/iOSFindBySet.java | 6 ++-- .../java_client/pagefactory/iOSFindBys.java | 8 ++--- .../java_client/pagefactory/iOSXCUITBy.java | 2 +- .../pagefactory/iOSXCUITFindAll.java | 12 ++++---- .../pagefactory/iOSXCUITFindBy.java | 8 ++--- .../pagefactory/iOSXCUITFindByAllSet.java | 10 +++---- .../pagefactory/iOSXCUITFindByChainSet.java | 10 +++---- .../pagefactory/iOSXCUITFindBySet.java | 7 ++--- .../pagefactory/iOSXCUITFindBys.java | 12 ++++---- .../AndroidPageObjectTest.java | 30 +++++++++---------- .../utils/ScreenshotStateTests.java | 12 ++++---- 41 files changed, 177 insertions(+), 161 deletions(-) diff --git a/google-style.xml b/google-style.xml index 6f3440428..06e2c452c 100755 --- a/google-style.xml +++ b/google-style.xml @@ -97,7 +97,7 @@ value="Package name ''{0}'' must match pattern ''{1}''."/> - + diff --git a/src/main/java/io/appium/java_client/ScreenshotState.java b/src/main/java/io/appium/java_client/ScreenshotState.java index d698819b1..1c8675eb7 100644 --- a/src/main/java/io/appium/java_client/ScreenshotState.java +++ b/src/main/java/io/appium/java_client/ScreenshotState.java @@ -16,6 +16,8 @@ package io.appium.java_client; +import static nu.pattern.OpenCV.loadShared; + import org.opencv.core.Core; import org.opencv.core.CvType; import org.opencv.core.Mat; @@ -32,8 +34,6 @@ import java.util.function.Function; import java.util.function.Supplier; -import static nu.pattern.OpenCV.loadShared; - public class ScreenshotState { private static final Duration DEFAULT_INTERVAL_MS = Duration.ofMillis(500); 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 187316b0c..b802cbbbc 100644 --- a/src/main/java/io/appium/java_client/pagefactory/AndroidBy.java +++ b/src/main/java/io/appium/java_client/pagefactory/AndroidBy.java @@ -17,7 +17,7 @@ package io.appium.java_client.pagefactory; /** - * Used to build a complex android automator locator + * Used to build a complex android automator locator. */ public @interface AndroidBy { /** 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 522e8a213..1f411a4a5 100644 --- a/src/main/java/io/appium/java_client/pagefactory/AndroidFindAll.java +++ b/src/main/java/io/appium/java_client/pagefactory/AndroidFindAll.java @@ -16,14 +16,14 @@ package io.appium.java_client.pagefactory; -import java.lang.annotation.Repeatable; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + /** * Used to mark a field on a Page/Screen Object to indicate that lookup should use a * series of {@link io.appium.java_client.pagefactory.AndroidBy} tags 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 4c5210691..bb17d861b 100644 --- a/src/main/java/io/appium/java_client/pagefactory/AndroidFindBy.java +++ b/src/main/java/io/appium/java_client/pagefactory/AndroidFindBy.java @@ -16,14 +16,14 @@ package io.appium.java_client.pagefactory; -import java.lang.annotation.Repeatable; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + /** * Used to mark a field on a Page Object to indicate an alternative mechanism for locating the diff --git a/src/main/java/io/appium/java_client/pagefactory/AndroidFindByAllSet.java b/src/main/java/io/appium/java_client/pagefactory/AndroidFindByAllSet.java index 6f224c6de..40e49415a 100644 --- a/src/main/java/io/appium/java_client/pagefactory/AndroidFindByAllSet.java +++ b/src/main/java/io/appium/java_client/pagefactory/AndroidFindByAllSet.java @@ -1,12 +1,12 @@ package io.appium.java_client.pagefactory; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + /** * Defines set of chained/possible locators. Each one locator * should be defined with {@link AndroidFindAll} diff --git a/src/main/java/io/appium/java_client/pagefactory/AndroidFindByChainSet.java b/src/main/java/io/appium/java_client/pagefactory/AndroidFindByChainSet.java index 9c0eba3da..bf1958767 100644 --- a/src/main/java/io/appium/java_client/pagefactory/AndroidFindByChainSet.java +++ b/src/main/java/io/appium/java_client/pagefactory/AndroidFindByChainSet.java @@ -1,12 +1,12 @@ package io.appium.java_client.pagefactory; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + /** * Defines set of chained/possible locators. Each one locator * should be defined with {@link io.appium.java_client.pagefactory.AndroidFindBys} diff --git a/src/main/java/io/appium/java_client/pagefactory/AndroidFindBySet.java b/src/main/java/io/appium/java_client/pagefactory/AndroidFindBySet.java index cb9ff3b71..08be7d053 100644 --- a/src/main/java/io/appium/java_client/pagefactory/AndroidFindBySet.java +++ b/src/main/java/io/appium/java_client/pagefactory/AndroidFindBySet.java @@ -16,13 +16,13 @@ package io.appium.java_client.pagefactory; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Retention; +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} 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 0bbb06bea..e8c0d2ae1 100644 --- a/src/main/java/io/appium/java_client/pagefactory/AndroidFindBys.java +++ b/src/main/java/io/appium/java_client/pagefactory/AndroidFindBys.java @@ -16,14 +16,14 @@ package io.appium.java_client.pagefactory; -import java.lang.annotation.Repeatable; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + /** * Used to mark a field on a Page Object to indicate that lookup should use * a series of {@link io.appium.java_client.pagefactory.AndroidBy} tags. 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 bed1058e4..69975e0fc 100644 --- a/src/main/java/io/appium/java_client/pagefactory/DefaultElementByBuilder.java +++ b/src/main/java/io/appium/java_client/pagefactory/DefaultElementByBuilder.java @@ -16,6 +16,11 @@ package io.appium.java_client.pagefactory; +import static java.util.Arrays.asList; +import static java.util.Arrays.sort; +import static java.util.Optional.ofNullable; +import static org.apache.commons.lang3.ArrayUtils.add; + import io.appium.java_client.pagefactory.bys.ContentMappedBy; import io.appium.java_client.pagefactory.bys.ContentType; import io.appium.java_client.pagefactory.bys.builder.AppiumByBuilder; @@ -34,12 +39,11 @@ import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.util.*; - -import static java.util.Arrays.asList; -import static java.util.Arrays.sort; -import static java.util.Optional.ofNullable; -import static org.apache.commons.lang3.ArrayUtils.add; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; public class DefaultElementByBuilder extends AppiumByBuilder { @@ -133,9 +137,9 @@ private By[] getBys(Class singleLocator, Class p1) { return -1; - } - else if (p2 < p1){ + } else if (p2 < p1) { return 1; - } - else { + } else { return 0; } - } catch (IllegalAccessException|InvocationTargetException e) { + } catch (IllegalAccessException | InvocationTargetException e) { throw new RuntimeException(e); } } diff --git a/src/main/java/io/appium/java_client/pagefactory/SelendroidBy.java b/src/main/java/io/appium/java_client/pagefactory/SelendroidBy.java index 61437c2d9..75933eba4 100644 --- a/src/main/java/io/appium/java_client/pagefactory/SelendroidBy.java +++ b/src/main/java/io/appium/java_client/pagefactory/SelendroidBy.java @@ -18,7 +18,7 @@ /** - * Used to build a complex selendroid locator + * Used to build a complex selendroid locator. */ public @interface SelendroidBy { /** 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 5e1352f56..8e2e56a79 100644 --- a/src/main/java/io/appium/java_client/pagefactory/SelendroidFindAll.java +++ b/src/main/java/io/appium/java_client/pagefactory/SelendroidFindAll.java @@ -16,9 +16,11 @@ package io.appium.java_client.pagefactory; -import java.lang.annotation.ElementType; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** @@ -27,7 +29,7 @@ * It will then search for all elements that match any criteria. Note that elements * are not guaranteed to be in document order. */ -@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE}) +@Retention(RUNTIME) @Target({FIELD, TYPE}) public @interface SelendroidFindAll { /** * It is a set of {@link io.appium.java_client.pagefactory.SelendroidBy} strategies which 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 3ebf0ac0b..146079a14 100644 --- a/src/main/java/io/appium/java_client/pagefactory/SelendroidFindBy.java +++ b/src/main/java/io/appium/java_client/pagefactory/SelendroidFindBy.java @@ -16,10 +16,12 @@ package io.appium.java_client.pagefactory; -import java.lang.annotation.ElementType; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @@ -30,7 +32,7 @@ * this allows users to quickly and easily create PageObjects. * using Selendroid UI selectors like, id, name, class name, tag and xpath */ -@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE}) +@Retention(RUNTIME) @Target({FIELD, TYPE}) @Repeatable(SelendroidFindBySet.class) public @interface SelendroidFindBy { /** diff --git a/src/main/java/io/appium/java_client/pagefactory/SelendroidFindByAllSet.java b/src/main/java/io/appium/java_client/pagefactory/SelendroidFindByAllSet.java index 6c8019dcc..0b83c223c 100644 --- a/src/main/java/io/appium/java_client/pagefactory/SelendroidFindByAllSet.java +++ b/src/main/java/io/appium/java_client/pagefactory/SelendroidFindByAllSet.java @@ -16,17 +16,19 @@ package io.appium.java_client.pagefactory; -import java.lang.annotation.ElementType; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + 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 SelendroidFindAll} */ -@Target(value = {ElementType.TYPE, ElementType.FIELD}) -@Retention(value = RetentionPolicy.RUNTIME) +@Target(value = {TYPE, FIELD}) +@Retention(value = RUNTIME) public @interface SelendroidFindByAllSet { /** * @return an array of {@link SelendroidFindAll} which builds a sequence of diff --git a/src/main/java/io/appium/java_client/pagefactory/SelendroidFindByChainSet.java b/src/main/java/io/appium/java_client/pagefactory/SelendroidFindByChainSet.java index a344e3a11..5824ed173 100644 --- a/src/main/java/io/appium/java_client/pagefactory/SelendroidFindByChainSet.java +++ b/src/main/java/io/appium/java_client/pagefactory/SelendroidFindByChainSet.java @@ -16,17 +16,19 @@ package io.appium.java_client.pagefactory; -import java.lang.annotation.ElementType; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + 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 SelendroidFindBys} */ -@Target(value = {ElementType.TYPE, ElementType.FIELD}) -@Retention(value = RetentionPolicy.RUNTIME) +@Target(value = {TYPE, FIELD}) +@Retention(value = RUNTIME) public @interface SelendroidFindByChainSet { /** * @return an array of {@link SelendroidFindBys} which builds a sequence of diff --git a/src/main/java/io/appium/java_client/pagefactory/SelendroidFindBySet.java b/src/main/java/io/appium/java_client/pagefactory/SelendroidFindBySet.java index 0fa8fa721..38e903966 100644 --- a/src/main/java/io/appium/java_client/pagefactory/SelendroidFindBySet.java +++ b/src/main/java/io/appium/java_client/pagefactory/SelendroidFindBySet.java @@ -16,17 +16,19 @@ package io.appium.java_client.pagefactory; -import java.lang.annotation.ElementType; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + 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) +@Target(value = {TYPE, FIELD}) +@Retention(value = RUNTIME) public @interface SelendroidFindBySet { /** * @return an array of {@link io.appium.java_client.pagefactory.SelendroidFindBy} which builds a sequence of 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 6a3fea463..6a7bd2f3a 100644 --- a/src/main/java/io/appium/java_client/pagefactory/SelendroidFindBys.java +++ b/src/main/java/io/appium/java_client/pagefactory/SelendroidFindBys.java @@ -16,16 +16,18 @@ package io.appium.java_client.pagefactory; -import java.lang.annotation.ElementType; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Used to mark a field on a Page Object to indicate that lookup should * use a series of {@link io.appium.java_client.pagefactory.SelendroidBy} tags. */ -@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE}) +@Retention(RUNTIME) @Target({FIELD, TYPE}) public @interface SelendroidFindBys { /** * It is a set of {@link io.appium.java_client.pagefactory.SelendroidBy} strategies which diff --git a/src/main/java/io/appium/java_client/pagefactory/WindowsBy.java b/src/main/java/io/appium/java_client/pagefactory/WindowsBy.java index 804fd86a8..892201cc6 100644 --- a/src/main/java/io/appium/java_client/pagefactory/WindowsBy.java +++ b/src/main/java/io/appium/java_client/pagefactory/WindowsBy.java @@ -17,7 +17,7 @@ package io.appium.java_client.pagefactory; /** - * Used to build a complex Windows automation locator + * Used to build a complex Windows automation locator. */ public @interface WindowsBy { diff --git a/src/main/java/io/appium/java_client/pagefactory/WindowsFindAll.java b/src/main/java/io/appium/java_client/pagefactory/WindowsFindAll.java index 6ff37fc39..5b1c7cf00 100644 --- a/src/main/java/io/appium/java_client/pagefactory/WindowsFindAll.java +++ b/src/main/java/io/appium/java_client/pagefactory/WindowsFindAll.java @@ -16,14 +16,14 @@ package io.appium.java_client.pagefactory; -import java.lang.annotation.Repeatable; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + /** * Used to mark a field on a Page/Screen Object to indicate that lookup should use a series * of {@link WindowsBy} tags diff --git a/src/main/java/io/appium/java_client/pagefactory/WindowsFindBy.java b/src/main/java/io/appium/java_client/pagefactory/WindowsFindBy.java index b4f1f914e..667814056 100644 --- a/src/main/java/io/appium/java_client/pagefactory/WindowsFindBy.java +++ b/src/main/java/io/appium/java_client/pagefactory/WindowsFindBy.java @@ -16,14 +16,14 @@ package io.appium.java_client.pagefactory; -import java.lang.annotation.Repeatable; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + /** * Used to mark a field on a Page Object to indicate an alternative mechanism for locating the * element or a list of elements. Used in conjunction with diff --git a/src/main/java/io/appium/java_client/pagefactory/WindowsFindByAllSet.java b/src/main/java/io/appium/java_client/pagefactory/WindowsFindByAllSet.java index 1b3344ea7..adbad0864 100644 --- a/src/main/java/io/appium/java_client/pagefactory/WindowsFindByAllSet.java +++ b/src/main/java/io/appium/java_client/pagefactory/WindowsFindByAllSet.java @@ -1,12 +1,12 @@ package io.appium.java_client.pagefactory; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + /** * Defines set of chained/possible locators. Each one locator * should be defined with {@link WindowsFindAll} diff --git a/src/main/java/io/appium/java_client/pagefactory/WindowsFindByChainSet.java b/src/main/java/io/appium/java_client/pagefactory/WindowsFindByChainSet.java index 1a9fe6297..b8a5bc03d 100644 --- a/src/main/java/io/appium/java_client/pagefactory/WindowsFindByChainSet.java +++ b/src/main/java/io/appium/java_client/pagefactory/WindowsFindByChainSet.java @@ -1,12 +1,12 @@ package io.appium.java_client.pagefactory; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + /** * Defines set of chained/possible locators. Each one locator * should be defined with {@link WindowsFindBys} diff --git a/src/main/java/io/appium/java_client/pagefactory/WindowsFindBySet.java b/src/main/java/io/appium/java_client/pagefactory/WindowsFindBySet.java index 9a8e4d07e..edf7de758 100644 --- a/src/main/java/io/appium/java_client/pagefactory/WindowsFindBySet.java +++ b/src/main/java/io/appium/java_client/pagefactory/WindowsFindBySet.java @@ -16,13 +16,13 @@ package io.appium.java_client.pagefactory; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + /** * Defines set of chained/possible locators. Each one locator * should be defined with {@link WindowsFindBy} diff --git a/src/main/java/io/appium/java_client/pagefactory/WindowsFindBys.java b/src/main/java/io/appium/java_client/pagefactory/WindowsFindBys.java index 59e5f02c3..5bd34f460 100644 --- a/src/main/java/io/appium/java_client/pagefactory/WindowsFindBys.java +++ b/src/main/java/io/appium/java_client/pagefactory/WindowsFindBys.java @@ -16,14 +16,14 @@ package io.appium.java_client.pagefactory; -import java.lang.annotation.Repeatable; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + /** * Used to mark a field on a Page Object to indicate that lookup should use * a series of {@link WindowsBy} tags. diff --git a/src/main/java/io/appium/java_client/pagefactory/bys/builder/ByChained.java b/src/main/java/io/appium/java_client/pagefactory/bys/builder/ByChained.java index 9b1c101ea..f25f1d3cc 100644 --- a/src/main/java/io/appium/java_client/pagefactory/bys/builder/ByChained.java +++ b/src/main/java/io/appium/java_client/pagefactory/bys/builder/ByChained.java @@ -42,6 +42,9 @@ private static AppiumFunction getSearchingFunction(By }; } + /** + * @param bys is a set of {@link org.openqa.selenium.By} which forms the chain of the searching. + */ public ByChained(By[] bys) { super(bys); checkNotNull(bys); diff --git a/src/main/java/io/appium/java_client/pagefactory/iOSBy.java b/src/main/java/io/appium/java_client/pagefactory/iOSBy.java index 9a8515d6a..0b7623bc6 100644 --- a/src/main/java/io/appium/java_client/pagefactory/iOSBy.java +++ b/src/main/java/io/appium/java_client/pagefactory/iOSBy.java @@ -18,7 +18,7 @@ /** - * Used to build a complex iOS automation locator + * Used to build a complex iOS automation locator. */ public @interface iOSBy { /** 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 9e03d7714..5754583d1 100644 --- a/src/main/java/io/appium/java_client/pagefactory/iOSFindAll.java +++ b/src/main/java/io/appium/java_client/pagefactory/iOSFindAll.java @@ -16,14 +16,14 @@ package io.appium.java_client.pagefactory; -import java.lang.annotation.Repeatable; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + /** * Used to mark a field on a Page/Screen Object to indicate that lookup should use a series * of {@link io.appium.java_client.pagefactory.iOSBy} tags 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 cb8125aed..5c365fe4a 100644 --- a/src/main/java/io/appium/java_client/pagefactory/iOSFindBy.java +++ b/src/main/java/io/appium/java_client/pagefactory/iOSFindBy.java @@ -16,14 +16,14 @@ package io.appium.java_client.pagefactory; -import java.lang.annotation.Repeatable; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + /** * Used to mark a field on a Page Object to indicate an alternative mechanism for locating the diff --git a/src/main/java/io/appium/java_client/pagefactory/iOSFindByAllSet.java b/src/main/java/io/appium/java_client/pagefactory/iOSFindByAllSet.java index 903e78afd..cbedac322 100644 --- a/src/main/java/io/appium/java_client/pagefactory/iOSFindByAllSet.java +++ b/src/main/java/io/appium/java_client/pagefactory/iOSFindByAllSet.java @@ -1,21 +1,21 @@ package io.appium.java_client.pagefactory; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + /** * Defines set of chained/possible locators. Each one locator - * should be defined with {@link iOSFindAll} + * should be defined with {@link io.appium.java_client.pagefactory.iOSFindAll} */ @Target(value = {TYPE, FIELD}) @Retention(value = RUNTIME) public @interface iOSFindByAllSet { /** - * @return an array of {@link iOSFindAll} which builds a sequence of + * @return an array of {@link io.appium.java_client.pagefactory.iOSFindAll} which builds a sequence of * the chained searching for elements or a set of possible locators */ iOSFindAll[] value(); diff --git a/src/main/java/io/appium/java_client/pagefactory/iOSFindByChainSet.java b/src/main/java/io/appium/java_client/pagefactory/iOSFindByChainSet.java index 972a51e53..5b6865dd1 100644 --- a/src/main/java/io/appium/java_client/pagefactory/iOSFindByChainSet.java +++ b/src/main/java/io/appium/java_client/pagefactory/iOSFindByChainSet.java @@ -1,21 +1,21 @@ package io.appium.java_client.pagefactory; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + /** * Defines set of chained/possible locators. Each one locator - * should be defined with {@link iOSFindBys} + * should be defined with {@link io.appium.java_client.pagefactory.iOSFindBys} */ @Target(value = {TYPE, FIELD}) @Retention(value = RUNTIME) public @interface iOSFindByChainSet { /** - * @return an array of {@link iOSFindBys} which builds a sequence of + * @return an array of {@link io.appium.java_client.pagefactory.iOSFindBys} which builds a sequence of * the chained searching for elements or a set of possible locators */ iOSFindBys[] value(); diff --git a/src/main/java/io/appium/java_client/pagefactory/iOSFindBySet.java b/src/main/java/io/appium/java_client/pagefactory/iOSFindBySet.java index 3faa4665b..2f876b878 100644 --- a/src/main/java/io/appium/java_client/pagefactory/iOSFindBySet.java +++ b/src/main/java/io/appium/java_client/pagefactory/iOSFindBySet.java @@ -16,13 +16,13 @@ package io.appium.java_client.pagefactory; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Retention; +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} 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 172f16992..9d2f0a4c3 100644 --- a/src/main/java/io/appium/java_client/pagefactory/iOSFindBys.java +++ b/src/main/java/io/appium/java_client/pagefactory/iOSFindBys.java @@ -16,14 +16,14 @@ package io.appium.java_client.pagefactory; -import java.lang.annotation.Repeatable; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + /** * Used to mark a field on a Page Object to indicate that lookup should use * a series of {@link io.appium.java_client.pagefactory.iOSBy} tags. diff --git a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITBy.java b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITBy.java index da0e44277..f3a1e8100 100644 --- a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITBy.java +++ b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITBy.java @@ -17,7 +17,7 @@ package io.appium.java_client.pagefactory; /** - * Used to build a complex iOS XCUIT mode locator + * Used to build a complex iOS XCUIT mode locator. */ public @interface iOSXCUITBy { diff --git a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindAll.java b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindAll.java index 71b065089..95af79c36 100644 --- a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindAll.java +++ b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindAll.java @@ -16,17 +16,17 @@ package io.appium.java_client.pagefactory; -import java.lang.annotation.Repeatable; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + /** * Used to mark a field on a Page/Screen Object to indicate that lookup should use a series - * of {@link iOSXCUITBy} tags + * of {@link io.appium.java_client.pagefactory.iOSXCUITBy} tags * It will then search for all elements that match any criteria. Note that elements * are not guaranteed to be in document order. */ @@ -34,7 +34,7 @@ @Repeatable(iOSXCUITFindByAllSet.class) public @interface iOSXCUITFindAll { /** - * It is a set of {@link iOSXCUITBy} strategies which may be + * It is a set of {@link io.appium.java_client.pagefactory.iOSXCUITBy} strategies which may be * used to find the target element. */ iOSXCUITBy[] value(); diff --git a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBy.java b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBy.java index f39499224..63caf7cf4 100644 --- a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBy.java +++ b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBy.java @@ -16,14 +16,14 @@ package io.appium.java_client.pagefactory; -import java.lang.annotation.Repeatable; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + @Retention(RUNTIME) @Target({FIELD, TYPE}) @Repeatable(iOSXCUITFindBySet.class) public @interface iOSXCUITFindBy { diff --git a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindByAllSet.java b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindByAllSet.java index 45506a002..a0adcf8f2 100644 --- a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindByAllSet.java +++ b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindByAllSet.java @@ -1,21 +1,21 @@ package io.appium.java_client.pagefactory; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + /** * Defines set of chained/possible locators. Each one locator - * should be defined with {@link iOSXCUITFindAll} + * should be defined with {@link io.appium.java_client.pagefactory.iOSXCUITFindAll} */ @Target(value = {TYPE, FIELD}) @Retention(value = RUNTIME) public @interface iOSXCUITFindByAllSet { /** - * @return an array of {@link iOSXCUITFindAll} which builds a sequence of + * @return an array of {@link io.appium.java_client.pagefactory.iOSXCUITFindAll} which builds a sequence of * the chained searching for elements or a set of possible locators */ iOSXCUITFindAll[] value(); diff --git a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindByChainSet.java b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindByChainSet.java index 27a18c7bb..056931c8a 100644 --- a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindByChainSet.java +++ b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindByChainSet.java @@ -1,21 +1,21 @@ package io.appium.java_client.pagefactory; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + /** * Defines set of chained/possible locators. Each one locator - * should be defined with {@link iOSXCUITFindBys} + * should be defined with {@link io.appium.java_client.pagefactory.iOSXCUITFindBys} */ @Target(value = {TYPE, FIELD}) @Retention(value = RUNTIME) public @interface iOSXCUITFindByChainSet { /** - * @return an array of {@link iOSXCUITFindBys} which builds a sequence of + * @return an array of {@link io.appium.java_client.pagefactory.iOSXCUITFindBys} which builds a sequence of * the chained searching for elements or a set of possible locators */ iOSXCUITFindBys[] value(); diff --git a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBySet.java b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBySet.java index fb0f6c599..2d3b0c02b 100644 --- a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBySet.java +++ b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBySet.java @@ -16,14 +16,13 @@ package io.appium.java_client.pagefactory; -import java.lang.annotation.Repeatable; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + @Retention(RUNTIME) @Target({FIELD, TYPE}) public @interface iOSXCUITFindBySet { /** diff --git a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBys.java b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBys.java index 847ec2b3f..ad241f445 100644 --- a/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBys.java +++ b/src/main/java/io/appium/java_client/pagefactory/iOSXCUITFindBys.java @@ -16,23 +16,23 @@ package io.appium.java_client.pagefactory; -import java.lang.annotation.Repeatable; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + /** * Used to mark a field on a Page Object to indicate that lookup should use - * a series of {@link iOSXCUITBy} tags. + * a series of {@link io.appium.java_client.pagefactory.iOSXCUITBy} tags. */ @Retention(RUNTIME) @Target({FIELD, TYPE}) @Repeatable(iOSXCUITFindByChainSet.class) public @interface iOSXCUITFindBys { /** - * It is a set of {@link iOSXCUITBy} strategies which build + * It is a set of {@link io.appium.java_client.pagefactory.iOSXCUITBy} strategies which build * the chain of the searching for the target element. */ iOSXCUITBy[] value(); 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 9bd6f9b81..550b58b6f 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 @@ -25,8 +25,15 @@ import io.appium.java_client.android.AndroidElement; import io.appium.java_client.android.BaseAndroidTest; -import io.appium.java_client.pagefactory.*; +import io.appium.java_client.pagefactory.AndroidBy; +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 org.junit.Before; import org.junit.Test; import org.openqa.selenium.NoSuchElementException; @@ -179,32 +186,27 @@ public class AndroidPageObjectTest extends BaseAndroidTest { @AndroidFindBy(id = "android:id/text1", priority = 2) @AndroidFindAll(value = { @AndroidBy(uiAutomator = "new UiSelector().resourceId(\"android:id/list\")"), - @AndroidBy(id = "android:id/fakeId") - }, priority = 1) + @AndroidBy(id = "android:id/fakeId")}, priority = 1) @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/content\")") private AndroidElement androidElementViewFoundByMixedSearching; @AndroidFindBy(id = "android:id/text1", priority = 2) @AndroidFindAll(value = { @AndroidBy(uiAutomator = "new UiSelector().resourceId(\"android:id/list\")"), - @AndroidBy(id = "android:id/fakeId") - }, priority = 1) + @AndroidBy(id = "android:id/fakeId")}, priority = 1) @AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/content\")") private List androidElementsViewFoundByMixedSearching; @AndroidFindBys({ @AndroidBy(uiAutomator = "new UiSelector().resourceId(\"android:id/content\")", priority = 1), - @AndroidBy(className = "android.widget.FrameLayout"), - }) - @AndroidFindBys({ - @AndroidBy(id = "android:id/text1", priority = 1), + @AndroidBy(className = "android.widget.FrameLayout")}) + @AndroidFindBys({@AndroidBy(id = "android:id/text1", priority = 1), @AndroidBy(uiAutomator = "new UiSelector().resourceId(\"android:id/list\")")}) private AndroidElement androidElementViewFoundByMixedSearching2; @AndroidFindBys({ @AndroidBy(uiAutomator = "new UiSelector().resourceId(\"android:id/content\")", priority = 1), - @AndroidBy(className = "android.widget.FrameLayout"), - }) + @AndroidBy(className = "android.widget.FrameLayout")}) @AndroidFindBys({ @AndroidBy(id = "android:id/text1", priority = 1), @AndroidBy(uiAutomator = "new UiSelector().resourceId(\"android:id/list\")")}) @@ -217,8 +219,7 @@ public class AndroidPageObjectTest extends BaseAndroidTest { @AndroidBy(uiAutomator = "new UiSelector().resourceId(\"android:id/content\")", priority = 1), @AndroidBy(id = "android:id/text1", priority = 3), @AndroidBy(uiAutomator = "new UiSelector().resourceId(\"android:id/list\")", priority = 2), - @AndroidBy(className = "android.widget.FrameLayout"), - }, priority = 2) + @AndroidBy(className = "android.widget.FrameLayout")}, priority = 2) @AndroidFindBy(id = "android:id/fakeId3", priority = 3) @AndroidFindBy(id = "android:id/fakeId4", priority = 4) private AndroidElement androidElementViewFoundByMixedSearching3; @@ -230,8 +231,7 @@ public class AndroidPageObjectTest extends BaseAndroidTest { @AndroidBy(uiAutomator = "new UiSelector().resourceId(\"android:id/content\")", priority = 1), @AndroidBy(id = "android:id/text1", priority = 3), @AndroidBy(uiAutomator = "new UiSelector().resourceId(\"android:id/list\")", priority = 2), - @AndroidBy(className = "android.widget.FrameLayout"), - }, priority = 2) + @AndroidBy(className = "android.widget.FrameLayout")}, priority = 2) @AndroidFindBy(id = "android:id/fakeId3", priority = 3) @AndroidFindBy(id = "android:id/fakeId4", priority = 4) private List androidElementsViewFoundByMixedSearching3; diff --git a/src/test/java/io/appium/java_client/utils/ScreenshotStateTests.java b/src/test/java/io/appium/java_client/utils/ScreenshotStateTests.java index 1868db56b..1f730a60e 100644 --- a/src/test/java/io/appium/java_client/utils/ScreenshotStateTests.java +++ b/src/test/java/io/appium/java_client/utils/ScreenshotStateTests.java @@ -1,5 +1,11 @@ package io.appium.java_client.utils; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.Matchers.greaterThanOrEqualTo; +import static org.hamcrest.Matchers.lessThan; +import static org.junit.Assert.assertThat; + import io.appium.java_client.ScreenshotState; import org.junit.Before; import org.junit.Test; @@ -11,12 +17,6 @@ import java.time.Duration; import java.util.Random; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.notNullValue; -import static org.hamcrest.Matchers.lessThan; -import static org.hamcrest.Matchers.greaterThanOrEqualTo; -import static org.junit.Assert.assertThat; - public class ScreenshotStateTests { private static final Random rand = new Random(); private static final Duration ONE_SECOND = Duration.ofSeconds(1); From 8fc9a82e6b17e6a4b6302297e4cc4ec1d070985c Mon Sep 17 00:00:00 2001 From: Sergey Tikhomirov Date: Sun, 21 May 2017 23:30:32 +0300 Subject: [PATCH 7/9] #565: the WIKI was updated --- docs/Page-objects.md | 63 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/docs/Page-objects.md b/docs/Page-objects.md index 9a34063ca..4d99c375b 100644 --- a/docs/Page-objects.md +++ b/docs/Page-objects.md @@ -145,7 +145,7 @@ RemoteWebElement someElement; List someElements; ``` -## Also possible combined variants: +## Also possible combined variants for target platforms: ```java import org.openqa.selenium.remote.RemoteWebElement; @@ -194,6 +194,67 @@ RemoteWebElement someElement; List someElements; ``` +## Mixed chain/any locator strategy + +Some locator-element could not be defined certainly sometimes. It may be defined as one of possible variants/chained locator. +If the using of _xpath_ is not convenient for some reasons so there are possible use cases + +### the chained searching + +```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; + +//it is necessary to define priorities at this case. The lower number means the higher priority. +//The default value is 0 (the highest priority) +@iOSFindBy(someStrategy1) +@iOSFindAll(value = {@iOSBy(subloctor1), @iOSBy(subloctor1)}, priority = 1) //there are some variants for +// this element at the chain +@iOSFindBy(someStrategy2, priority = 2) +@iOSFindBy(someStrategy3, priority = 3) +RemoteWebElement someElement; + + +@iOSFindBy(someStrategy1) +@iOSFindAll(value = {@iOSBy(subloctor1), @iOSBy(subloctor1)}, priority = 1) //there are some variants for +// this element at the chain +@iOSFindBy(someStrategy2, priority = 2) +@iOSFindBy(someStrategy3, priority = 3) +List someElements; +``` + +### all possible + +```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; + +//it is not necessary to define priorities at this case. But it can manage the searching. +//The lower number means the higher priority. +//The default value is 0 (the highest priority) +@HowToUseLocators(iOSAutomation = ALL_POSSIBLE) +@iOSFindBy(someStrategy1) +@iOSFindBys(value = {@iOSBy(subloctor1), @iOSBy(subloctor1)}, priority = 1) //this possible variant is +// the chain +@iOSFindBy(someStrategy2, priority = 2) +@iOSFindBy(someStrategy3, priority = 3) +RemoteWebElement someElement; + + + +@HowToUseLocators(iOSAutomation = ALL_POSSIBLE) +@iOSFindBy(someStrategy1) +@iOSFindBys(value = {@iOSBy(subloctor1), @iOSBy(subloctor1)}, priority = 1) //this possible variant is +// the chain +@iOSFindBy(someStrategy2, priority = 2) +@iOSFindBy(someStrategy3, priority = 3) +List someElements; +``` + # Appium Java client is integrated with Selenium PageFactory by AppiumFieldDecorator. Object fields are populated as below: From 5a51da0876a7d6a225f666e7e0e6cce3ea21437a Mon Sep 17 00:00:00 2001 From: Sergey Tikhomirov Date: Sat, 27 May 2017 00:25:20 +0300 Subject: [PATCH 8/9] #565: Issues which were found by codecy were fixed Also documentation was improved --- docs/Page-objects.md | 4 +- .../pagefactory/DefaultElementByBuilder.java | 56 +++++++++---------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/docs/Page-objects.md b/docs/Page-objects.md index 4d99c375b..e055e1a72 100644 --- a/docs/Page-objects.md +++ b/docs/Page-objects.md @@ -238,7 +238,7 @@ import org.openqa.selenium.support.FindBy; //The default value is 0 (the highest priority) @HowToUseLocators(iOSAutomation = ALL_POSSIBLE) @iOSFindBy(someStrategy1) -@iOSFindBys(value = {@iOSBy(subloctor1), @iOSBy(subloctor1)}, priority = 1) //this possible variant is +@iOSFindAll(value = {@iOSBy(subloctor1), @iOSBy(subloctor1)}, priority = 1) //this possible variant is // the chain @iOSFindBy(someStrategy2, priority = 2) @iOSFindBy(someStrategy3, priority = 3) @@ -248,7 +248,7 @@ RemoteWebElement someElement; @HowToUseLocators(iOSAutomation = ALL_POSSIBLE) @iOSFindBy(someStrategy1) -@iOSFindBys(value = {@iOSBy(subloctor1), @iOSBy(subloctor1)}, priority = 1) //this possible variant is +@iOSFindAll(value = {@iOSBy(subloctor1), @iOSBy(subloctor1)}, priority = 1) //this possible variant is // the chain @iOSFindBy(someStrategy2, priority = 2) @iOSFindBy(someStrategy3, priority = 3) 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 69975e0fc..78bddc4ea 100644 --- a/src/main/java/io/appium/java_client/pagefactory/DefaultElementByBuilder.java +++ b/src/main/java/io/appium/java_client/pagefactory/DefaultElementByBuilder.java @@ -232,41 +232,41 @@ private By returnMappedBy(By byDefault, By nativeAppBy) { private static class AnnotationComparator implements Comparator { - @Override - public int compare(Annotation o1, Annotation o2) { - int p1; - int p2; - Method priority1; - Method priority2; - - Class c1 = o1.annotationType(); - Class c2 = o2.annotationType(); - + private static Method getPriorityMethod(Class clazz) { try { - priority1 = c1.getMethod(PRIORITY, ANNOTATION_ARGUMENTS); + return clazz.getMethod(PRIORITY, ANNOTATION_ARGUMENTS); } catch (NoSuchMethodException e) { - throw new ClassCastException(String.format("Class %s has no '%s' method", c1.getName(), PRIORITY)); + throw new ClassCastException(String.format("Class %s has no '%s' method", clazz.getName(), PRIORITY)); } + } + private static int getPriorityValue(Method priorityMethod, Annotation annotation, + Class clazz) { try { - priority2 = c2.getMethod(PRIORITY, ANNOTATION_ARGUMENTS); - } catch (NoSuchMethodException e) { - throw new ClassCastException(String.format("Class %s has no '%s' method", c2.getName(), PRIORITY)); + return (int) priorityMethod.invoke(annotation, ANNOTATION_PARAMETERS); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new IllegalArgumentException(String + .format("It is impossible to get priority. Annotation class: %s", clazz.toString()), e); } + } - try { - p1 = (int) priority1.invoke(o1, ANNOTATION_PARAMETERS); - p2 = (int) priority2.invoke(o2, ANNOTATION_PARAMETERS); - - if (p2 > p1) { - return -1; - } else if (p2 < p1) { - return 1; - } else { - return 0; - } - } catch (IllegalAccessException | InvocationTargetException e) { - throw new RuntimeException(e); + @Override + public int compare(Annotation o1, Annotation o2) { + Class c1 = o1.annotationType(); + Class c2 = o2.annotationType(); + + Method priority1 = getPriorityMethod(c1); + Method priority2 = getPriorityMethod(c2); + + int p1 = getPriorityValue(priority1, o1, c1); + int p2 = getPriorityValue(priority2, o2, c2); + + if (p2 > p1) { + return -1; + } else if (p2 < p1) { + return 1; + } else { + return 0; } } } From a7362596a09bd3bbcc65001b449a8baf38c8b598 Mon Sep 17 00:00:00 2001 From: Sergey Tikhomirov Date: Mon, 29 May 2017 23:53:37 +0300 Subject: [PATCH 9/9] #565: The work on remarks --- docs/Page-objects.md | 16 ++-- .../pagefactory/DefaultElementByBuilder.java | 86 ++++++++++--------- 2 files changed, 52 insertions(+), 50 deletions(-) diff --git a/docs/Page-objects.md b/docs/Page-objects.md index e055e1a72..7c41cc612 100644 --- a/docs/Page-objects.md +++ b/docs/Page-objects.md @@ -210,16 +210,16 @@ import org.openqa.selenium.support.FindBy; //it is necessary to define priorities at this case. The lower number means the higher priority. //The default value is 0 (the highest priority) @iOSFindBy(someStrategy1) -@iOSFindAll(value = {@iOSBy(subloctor1), @iOSBy(subloctor1)}, priority = 1) //there are some variants for -// this element at the chain +@iOSFindAll(value = {@iOSBy(subloctor1), @iOSBy(subloctor1)}, priority = 1) //it means that the chained searching contains +//the searching by all possible locators as the element of the chain @iOSFindBy(someStrategy2, priority = 2) @iOSFindBy(someStrategy3, priority = 3) RemoteWebElement someElement; @iOSFindBy(someStrategy1) -@iOSFindAll(value = {@iOSBy(subloctor1), @iOSBy(subloctor1)}, priority = 1) //there are some variants for -// this element at the chain +@iOSFindAll(value = {@iOSBy(subloctor1), @iOSBy(subloctor1)}, priority = 1) //it means that the chained searching contains +//the searching by all possible locators as the element of the chain @iOSFindBy(someStrategy2, priority = 2) @iOSFindBy(someStrategy3, priority = 3) List someElements; @@ -238,8 +238,8 @@ import org.openqa.selenium.support.FindBy; //The default value is 0 (the highest priority) @HowToUseLocators(iOSAutomation = ALL_POSSIBLE) @iOSFindBy(someStrategy1) -@iOSFindAll(value = {@iOSBy(subloctor1), @iOSBy(subloctor1)}, priority = 1) //this possible variant is -// the chain +@iOSFindBys(value = {@iOSBy(subloctor1), @iOSBy(subloctor1)}, priority = 1) //it means that the searching by all possible locators +// contains the searching by chained locator as one of all possible variants @iOSFindBy(someStrategy2, priority = 2) @iOSFindBy(someStrategy3, priority = 3) RemoteWebElement someElement; @@ -248,8 +248,8 @@ RemoteWebElement someElement; @HowToUseLocators(iOSAutomation = ALL_POSSIBLE) @iOSFindBy(someStrategy1) -@iOSFindAll(value = {@iOSBy(subloctor1), @iOSBy(subloctor1)}, priority = 1) //this possible variant is -// the chain +@iOSFindBys(value = {@iOSBy(subloctor1), @iOSBy(subloctor1)}, priority = 1) //it means that the searching by all possible locators +// contains the searching by chained locator as one of all possible variants @iOSFindBy(someStrategy2, priority = 2) @iOSFindBy(someStrategy3, priority = 3) List someElements; 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 78bddc4ea..24a3fd581 100644 --- a/src/main/java/io/appium/java_client/pagefactory/DefaultElementByBuilder.java +++ b/src/main/java/io/appium/java_client/pagefactory/DefaultElementByBuilder.java @@ -16,10 +16,9 @@ package io.appium.java_client.pagefactory; +import static java.lang.Integer.signum; import static java.util.Arrays.asList; -import static java.util.Arrays.sort; import static java.util.Optional.ofNullable; -import static org.apache.commons.lang3.ArrayUtils.add; import io.appium.java_client.pagefactory.bys.ContentMappedBy; import io.appium.java_client.pagefactory.bys.ContentType; @@ -40,29 +39,31 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; +import java.util.Arrays; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; public class DefaultElementByBuilder extends AppiumByBuilder { private static final String PRIORITY = "priority"; private static final String VALUE = "value"; - private static final Class[] ANNOTATION_ARGUMENTS = new Class[] {}; - private static final Object[] ANNOTATION_PARAMETERS = new Object[] {}; + private static final Class[] ANNOTATION_ARGUMENTS = new Class[]{}; + private static final Object[] ANNOTATION_PARAMETERS = new Object[]{}; public DefaultElementByBuilder(String platform, String automation) { super(platform, automation); } private static void checkDisallowedAnnotationPairs(Annotation a1, Annotation a2) - throws IllegalArgumentException { + throws IllegalArgumentException { if (a1 != null && a2 != null) { throw new IllegalArgumentException( - "If you use a '@" + a1.getClass().getSimpleName() + "' annotation, " - + "you must not also use a '@" + a2.getClass().getSimpleName() - + "' annotation"); + "If you use a '@" + a1.getClass().getSimpleName() + "' annotation, " + + "you must not also use a '@" + a2.getClass().getSimpleName() + + "' annotation"); } } @@ -78,7 +79,8 @@ private static By buildMobileBy(LocatorGroupStrategy locatorGroupStrategy, By[] return new ByChained(bys); } - @Override protected void assertValidAnnotations() { + @Override + protected void assertValidAnnotations() { AnnotatedElement annotatedElement = annotatedElementContainer.getAnnotated(); FindBy findBy = annotatedElement.getAnnotation(FindBy.class); FindBys findBys = annotatedElement.getAnnotation(FindBys.class); @@ -88,7 +90,8 @@ private static By buildMobileBy(LocatorGroupStrategy locatorGroupStrategy, By[] checkDisallowedAnnotationPairs(findBys, findAll); } - @Override protected By buildDefaultBy() { + @Override + protected By buildDefaultBy() { AnnotatedElement annotatedElement = annotatedElementContainer.getAnnotated(); By defaultBy = null; FindBy findBy = annotatedElement.getAnnotation(FindBy.class); @@ -117,79 +120,83 @@ private By[] getBys(Class singleLocator, Class annotations = new ArrayList<>(asList(annotatedElement.getAnnotationsByType(singleLocator))); + List annotations = new ArrayList<>(asList(annotatedElement.getAnnotationsByType(singleLocator))); annotations.addAll(asList(annotatedElement.getAnnotationsByType(chainedLocator))); annotations.addAll(asList(annotatedElement.getAnnotationsByType(allLocator))); - Annotation[] annotationsArray = annotations.toArray(new Annotation[]{}); - sort(annotationsArray, comparator); - By[] result = new By[] {}; + annotations.sort(comparator); + List result = new ArrayList<>(); - for (Annotation a: annotationsArray) { + for (Annotation a : annotations) { Class annotationClass = a.annotationType(); if (singleLocator.equals(annotationClass)) { - result = add(result, createBy(new Annotation[] {a}, HowToUseSelectors.USE_ONE)); + result.add(createBy(new Annotation[]{a}, HowToUseSelectors.USE_ONE)); continue; } Method value; - Annotation[] set; + Annotation[] subLocators; try { value = annotationClass.getMethod(VALUE, ANNOTATION_ARGUMENTS); - set = (Annotation[]) value.invoke(a, ANNOTATION_PARAMETERS); + subLocators = (Annotation[]) value.invoke(a, ANNOTATION_PARAMETERS); } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { throw new ClassCastException(String.format("The annotation '%s' has no convenient '%s' method which " + "returns array of annotations", annotationClass.getName(), VALUE)); } - sort(set, comparator); + Arrays.sort(subLocators, comparator); if (chainedLocator.equals(annotationClass)) { - result = add(result, createBy(set, HowToUseSelectors.BUILD_CHAINED)); + result.add(createBy(subLocators, HowToUseSelectors.BUILD_CHAINED)); continue; } if (allLocator.equals(annotationClass)) { - result = add(result, createBy(set, HowToUseSelectors.USE_ANY)); + result.add(createBy(subLocators, HowToUseSelectors.USE_ANY)); } } - return result; + return result.toArray(new By[result.size()]); } - @Override protected By buildMobileNativeBy() { + @Override + protected By buildMobileNativeBy() { AnnotatedElement annotatedElement = annotatedElementContainer.getAnnotated(); HowToUseLocators howToUseLocators = annotatedElement.getAnnotation(HowToUseLocators.class); + Optional howToUseLocatorsOptional = ofNullable(howToUseLocators); + By result = null; if (isSelendroidAutomation()) { - result = buildMobileBy(howToUseLocators != null ? howToUseLocators.selendroidAutomation() : null, + result = buildMobileBy(howToUseLocatorsOptional + .map(HowToUseLocators::selendroidAutomation).orElse(null), getBys(SelendroidFindBy.class, SelendroidFindBys.class, SelendroidFindAll.class)); } - if (isAndroid() && result == null) { - result = buildMobileBy(howToUseLocators != null ? howToUseLocators.androidAutomation() : null, + if (isAndroid() && result == null) { + return buildMobileBy(howToUseLocatorsOptional.map(HowToUseLocators::androidAutomation).orElse(null), getBys(AndroidFindBy.class, AndroidFindBys.class, AndroidFindAll.class)); } - if (isIOSXcuit() && result == null) { - result = buildMobileBy(howToUseLocators != null ? howToUseLocators.iOSXCUITAutomation() : null, + if (isIOSXcuit()) { + result = buildMobileBy(howToUseLocatorsOptional.map(HowToUseLocators::iOSXCUITAutomation).orElse(null), getBys(iOSXCUITFindBy.class, iOSXCUITFindBys.class, iOSXCUITFindAll.class)); } if (isIOS() && result == null) { - result = buildMobileBy(howToUseLocators != null ? howToUseLocators.iOSAutomation() : null, + return buildMobileBy(howToUseLocatorsOptional.map(HowToUseLocators::iOSAutomation).orElse(null), getBys(iOSFindBy.class, iOSFindBys.class, iOSFindAll.class)); } - if (isWindows() && result == null) { - result = buildMobileBy(howToUseLocators != null ? howToUseLocators.windowsAutomation() : null, + if (isWindows()) { + return buildMobileBy(howToUseLocatorsOptional.map(HowToUseLocators::windowsAutomation).orElse(null), getBys(WindowsFindBy.class, WindowsFindBys.class, WindowsFindAll.class)); } return ofNullable(result).orElse(null); } - @Override public boolean isLookupCached() { + @Override + public boolean isLookupCached() { AnnotatedElement annotatedElement = annotatedElementContainer.getAnnotated(); return (annotatedElement.getAnnotation(CacheLookup.class) != null); } @@ -201,7 +208,8 @@ private By returnMappedBy(By byDefault, By nativeAppBy) { return new ContentMappedBy(contentMap); } - @Override public By buildBy() { + @Override + public By buildBy() { assertValidAnnotations(); By defaultBy = buildDefaultBy(); @@ -211,14 +219,14 @@ private By returnMappedBy(By byDefault, By nativeAppBy) { if (defaultBy == null && mobileNativeBy == null) { defaultBy = - new ByIdOrName(((Field) annotatedElementContainer.getAnnotated()).getName()); + new ByIdOrName(((Field) annotatedElementContainer.getAnnotated()).getName()); mobileNativeBy = new By.ById(idOrName); return returnMappedBy(defaultBy, mobileNativeBy); } if (defaultBy == null) { defaultBy = - new ByIdOrName(((Field) annotatedElementContainer.getAnnotated()).getName()); + new ByIdOrName(((Field) annotatedElementContainer.getAnnotated()).getName()); return returnMappedBy(defaultBy, mobileNativeBy); } @@ -261,13 +269,7 @@ public int compare(Annotation o1, Annotation o2) { int p1 = getPriorityValue(priority1, o1, c1); int p2 = getPriorityValue(priority2, o2, c2); - if (p2 > p1) { - return -1; - } else if (p2 < p1) { - return 1; - } else { - return 0; - } + return signum(p1 - p2); } } } \ No newline at end of file