Skip to content

Commit 69ab315

Browse files
#565: The feature was completed
- bug fixes - test coverage
1 parent 29336b8 commit 69ab315

File tree

18 files changed

+459
-61
lines changed

18 files changed

+459
-61
lines changed
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License");
3+
* you may not use this file except in compliance with the License.
4+
* See the NOTICE file distributed with this work for additional
5+
* information regarding copyright ownership.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.appium.java_client.pagefactory;
18+
19+
/**
20+
* Used to build a complex android automator locator
21+
*/
22+
public @interface AndroidBy {
23+
/**
24+
* It is an is Android UIAutomator string.
25+
* Read http://developer.android.com/intl/ru/tools/testing-support-library/
26+
* index.html#uia-apis
27+
*/
28+
String uiAutomator() default "";
29+
30+
/**
31+
* It an UI automation accessibility Id which is a convenient to Android.
32+
* About Android accessibility
33+
* https://developer.android.com/intl/ru/training/accessibility/accessible-app.html
34+
*/
35+
String accessibility() default "";
36+
37+
/**
38+
* It is an id of the target element.
39+
*/
40+
String id() default "";
41+
42+
/**
43+
* It is a className of the target element.
44+
*/
45+
String className() default "";
46+
47+
/**
48+
* It is a desired element tag.
49+
*/
50+
String tagName() default "";
51+
52+
/**
53+
* It is a xpath to the target element.
54+
*/
55+
String xpath() default "";
56+
57+
/**
58+
* @return priority of the searching. Higher number means lower priority.
59+
*/
60+
int priority() default 0;
61+
}

src/main/java/io/appium/java_client/pagefactory/AndroidFindAll.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,18 @@
2626

2727
/**
2828
* Used to mark a field on a Page/Screen Object to indicate that lookup should use a
29-
* series of {@link io.appium.java_client.pagefactory.AndroidFindBy} tags
29+
* series of {@link io.appium.java_client.pagefactory.AndroidBy} tags
3030
* It will then search for all elements that match any criteria. Note that elements
3131
* are not guaranteed to be in document order.
3232
*/
3333
@Retention(RUNTIME) @Target({FIELD, TYPE})
3434
@Repeatable(AndroidFindByAllSet.class)
3535
public @interface AndroidFindAll {
3636
/**
37-
* It is a set of {@link io.appium.java_client.pagefactory.AndroidFindBy} strategies which may
37+
* It is a set of {@link io.appium.java_client.pagefactory.AndroidBy} strategies which may
3838
* be used to find the target element.
3939
*/
40-
AndroidFindBy[] value();
40+
AndroidBy[] value();
4141

4242
/**
4343
* @return priority of the searching. Higher number means lower priority.

src/main/java/io/appium/java_client/pagefactory/AndroidFindBys.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,16 @@
2626

2727
/**
2828
* Used to mark a field on a Page Object to indicate that lookup should use
29-
* a series of {@link io.appium.java_client.pagefactory.AndroidFindBy} tags.
29+
* a series of {@link io.appium.java_client.pagefactory.AndroidBy} tags.
3030
*/
3131
@Retention(RUNTIME) @Target({FIELD, TYPE})
3232
@Repeatable(AndroidFindByChainSet.class)
3333
public @interface AndroidFindBys {
3434
/**
35-
* It is a set of {@link io.appium.java_client.pagefactory.AndroidFindBy} strategies which build
35+
* It is a set of {@link io.appium.java_client.pagefactory.AndroidBy} strategies which build
3636
* the chain of the searching for the target element.
3737
*/
38-
AndroidFindBy[] value();
38+
AndroidBy[] value();
3939

4040
/**
4141
* @return priority of the searching. Higher number means lower priority.

src/main/java/io/appium/java_client/pagefactory/DefaultElementByBuilder.java

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,12 @@
3434
import java.lang.reflect.Field;
3535
import java.lang.reflect.InvocationTargetException;
3636
import java.lang.reflect.Method;
37-
import java.util.Comparator;
38-
import java.util.HashMap;
39-
import java.util.Map;
37+
import java.util.*;
4038

39+
import static java.util.Arrays.asList;
4140
import static java.util.Arrays.sort;
4241
import static java.util.Optional.ofNullable;
4342
import static org.apache.commons.lang3.ArrayUtils.add;
44-
import static org.apache.commons.lang3.ArrayUtils.addAll;
4543

4644
public class DefaultElementByBuilder extends AppiumByBuilder {
4745

@@ -115,15 +113,16 @@ private By[] getBys(Class<? extends Annotation> singleLocator, Class<? extends A
115113
AnnotationComparator comparator = new AnnotationComparator();
116114
AnnotatedElement annotatedElement = annotatedElementContainer.getAnnotated();
117115

118-
Annotation[] annotations = annotatedElement.getAnnotationsByType(singleLocator);
119-
annotations = addAll(annotations, annotatedElement.getAnnotationsByType(chainedLocator));
120-
annotations = addAll(annotations, annotatedElement.getAnnotationsByType(allLocator));
116+
List<Annotation> annotations = new ArrayList<>(asList(annotatedElement.getAnnotationsByType(singleLocator)));
117+
annotations.addAll(asList(annotatedElement.getAnnotationsByType(chainedLocator)));
118+
annotations.addAll(asList(annotatedElement.getAnnotationsByType(allLocator)));
121119

122-
sort(annotations, comparator);
120+
Annotation[] annotationsArray = annotations.toArray(new Annotation[]{});
121+
sort(annotationsArray, comparator);
123122
By[] result = new By[] {};
124123

125-
for (Annotation a: annotations) {
126-
Class<?> annotationClass = a.getClass().getInterfaces()[0];
124+
for (Annotation a: annotationsArray) {
125+
Class<?> annotationClass = a.annotationType();
127126
if (singleLocator.equals(annotationClass)) {
128127
result = add(result, createBy(new Annotation[] {a}, HowToUseSelectors.USE_ONE));
129128
continue;
@@ -231,32 +230,34 @@ private static class AnnotationComparator implements Comparator<Annotation> {
231230

232231
@Override
233232
public int compare(Annotation o1, Annotation o2) {
234-
int priority1;
235-
int priority2;
236-
Method priority;
233+
int p1;
234+
int p2;
235+
Method priority1;
236+
Method priority2;
237237

238-
Class<?> c1 = o1.getClass().getInterfaces()[0];
239-
Class<?> c2 = o2.getClass().getInterfaces()[0];
238+
Class<?> c1 = o1.annotationType();
239+
Class<?> c2 = o2.annotationType();
240240

241-
if (!c1.equals(c2)) {
242-
throw new ClassCastException(String.format("Given annotations have different classes (%s, %s). " +
243-
"Annotations of the same classes are required.", c1.getName(), c2.getName()));
241+
try {
242+
priority1 = c1.getMethod(PRIORITY, ANNOTATION_ARGUMENTS);
243+
} catch (NoSuchMethodException e) {
244+
throw new ClassCastException(String.format("Class %s has no '%s' method", c1.getName(), PRIORITY));
244245
}
245246

246247
try {
247-
priority = c1.getMethod(PRIORITY, ANNOTATION_ARGUMENTS);
248+
priority2 = c2.getMethod(PRIORITY, ANNOTATION_ARGUMENTS);
248249
} catch (NoSuchMethodException e) {
249-
throw new ClassCastException(String.format("Class %s has no '%s' method", c1.getName(), PRIORITY));
250+
throw new ClassCastException(String.format("Class %s has no '%s' method", c2.getName(), PRIORITY));
250251
}
251252

252253
try {
253-
priority1 = (int) priority.invoke(o1, ANNOTATION_PARAMETERS);
254-
priority2 = (int) priority.invoke(o2, ANNOTATION_PARAMETERS);
254+
p1 = (int) priority1.invoke(o1, ANNOTATION_PARAMETERS);
255+
p2 = (int) priority2.invoke(o2, ANNOTATION_PARAMETERS);
255256

256-
if (priority2 > priority1) {
257+
if (p2 > p1) {
257258
return -1;
258259
}
259-
else if (priority2 < priority1){
260+
else if (p2 < p1){
260261
return 1;
261262
}
262263
else {
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License");
3+
* you may not use this file except in compliance with the License.
4+
* See the NOTICE file distributed with this work for additional
5+
* information regarding copyright ownership.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.appium.java_client.pagefactory;
18+
19+
20+
/**
21+
* Used to build a complex selendroid locator
22+
*/
23+
public @interface SelendroidBy {
24+
/**
25+
* It is an id of the target element.
26+
*/
27+
String id() default "";
28+
29+
/**
30+
* It is used in Selendroid mode instead of accessibility id.
31+
*/
32+
String name() default "";
33+
34+
/**
35+
* It is a className of the target element.
36+
*/
37+
String className() default "";
38+
39+
/**
40+
* It is a desired element tag.
41+
*/
42+
String tagName() default "";
43+
44+
/**
45+
* It is a xpath to the target element.
46+
*/
47+
String xpath() default "";
48+
49+
/**
50+
* It is a text of the desired element.
51+
*/
52+
String linkText() default "";
53+
54+
/**
55+
* It is a part of the text of the desired element.
56+
*/
57+
String partialLinkText() default "";
58+
59+
/**
60+
* @return priority of the searching. Higher number means lower priority.
61+
*/
62+
int priority() default 0;
63+
}

src/main/java/io/appium/java_client/pagefactory/SelendroidFindAll.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,17 @@
2323

2424
/**
2525
* Used to mark a field on a Page/Screen Object to indicate that lookup should use a
26-
* series of {@link io.appium.java_client.pagefactory.SelendroidFindBy} tags
26+
* series of {@link io.appium.java_client.pagefactory.SelendroidBy} tags
2727
* It will then search for all elements that match any criteria. Note that elements
2828
* are not guaranteed to be in document order.
2929
*/
3030
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE})
3131
public @interface SelendroidFindAll {
3232
/**
33-
* It is a set of {@link io.appium.java_client.pagefactory.SelendroidFindBy} strategies which
33+
* It is a set of {@link io.appium.java_client.pagefactory.SelendroidBy} strategies which
3434
* may be used to find the target element.
3535
*/
36-
SelendroidFindBy[] value();
36+
SelendroidBy[] value();
3737

3838
/**
3939
* @return priority of the searching. Higher number means lower priority.

src/main/java/io/appium/java_client/pagefactory/SelendroidFindBys.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,15 @@
2323

2424
/**
2525
* Used to mark a field on a Page Object to indicate that lookup should
26-
* use a series of {@link io.appium.java_client.pagefactory.SelendroidFindBy} tags.
26+
* use a series of {@link io.appium.java_client.pagefactory.SelendroidBy} tags.
2727
*/
2828
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE})
2929
public @interface SelendroidFindBys {
3030
/**
31-
* It is a set of {@link io.appium.java_client.pagefactory.SelendroidFindBy} strategies which
31+
* It is a set of {@link io.appium.java_client.pagefactory.SelendroidBy} strategies which
3232
* build the chain of the searching for the target element.
3333
*/
34-
SelendroidFindBy[] value();
34+
SelendroidBy[] value();
3535

3636
/**
3737
* @return priority of the searching. Higher number means lower priority.
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License");
3+
* you may not use this file except in compliance with the License.
4+
* See the NOTICE file distributed with this work for additional
5+
* information regarding copyright ownership.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.appium.java_client.pagefactory;
18+
19+
/**
20+
* Used to build a complex Windows automation locator
21+
*/
22+
public @interface WindowsBy {
23+
24+
/**
25+
* It is an is Windows automator string.
26+
*/
27+
String windowsAutomation() default "";
28+
29+
/**
30+
* It an UI automation accessibility Id which is a convenient to Windows.
31+
*/
32+
String accessibility() default "";
33+
34+
/**
35+
* It is an id of the target element.
36+
*/
37+
String id() default "";
38+
39+
/**
40+
* It is a className of the target element.
41+
*/
42+
String className() default "";
43+
44+
/**
45+
* It is a desired element tag.
46+
*/
47+
String tagName() default "";
48+
49+
/**
50+
* It is a xpath to the target element.
51+
*/
52+
String xpath() default "";
53+
54+
/**
55+
* @return priority of the searching. Higher number means lower priority.
56+
*/
57+
int priority() default 0;
58+
}

src/main/java/io/appium/java_client/pagefactory/WindowsFindAll.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,18 @@
2626

2727
/**
2828
* Used to mark a field on a Page/Screen Object to indicate that lookup should use a series
29-
* of {@link WindowsFindBy} tags
29+
* of {@link WindowsBy} tags
3030
* It will then search for all elements that match any criteria. Note that elements
3131
* are not guaranteed to be in document order.
3232
*/
3333
@Retention(RUNTIME) @Target({FIELD, TYPE})
3434
@Repeatable(WindowsFindByAllSet.class)
3535
public @interface WindowsFindAll {
3636
/**
37-
* It is a set of {@link WindowsFindBy} strategies which may be
37+
* It is a set of {@link WindowsBy} strategies which may be
3838
* used to find the target element.
3939
*/
40-
WindowsFindBy[] value();
40+
WindowsBy[] value();
4141

4242
/**
4343
* @return priority of the searching. Higher number means lower priority.

src/main/java/io/appium/java_client/pagefactory/WindowsFindBys.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,16 @@
2626

2727
/**
2828
* Used to mark a field on a Page Object to indicate that lookup should use
29-
* a series of {@link WindowsFindBy} tags.
29+
* a series of {@link WindowsBy} tags.
3030
*/
3131
@Retention(RUNTIME) @Target({FIELD, TYPE})
3232
@Repeatable(WindowsFindByChainSet.class)
3333
public @interface WindowsFindBys {
3434
/**
35-
* It is a set of {@link WindowsFindBy} strategies which build
35+
* It is a set of {@link WindowsBy} strategies which build
3636
* the chain of the searching for the target element.
3737
*/
38-
WindowsFindBy[] value();
38+
WindowsBy[] value();
3939

4040
/**
4141
* @return priority of the searching. Higher number means lower priority.

0 commit comments

Comments
 (0)