Skip to content

Commit 575c1e0

Browse files
committed
[+] Add support for selendroid locators in page object annotations
1 parent 0721b56 commit 575c1e0

File tree

5 files changed

+109
-4
lines changed

5 files changed

+109
-4
lines changed

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

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,12 +137,14 @@ By getBy(Annotation annotation) {
137137

138138
private final Field mobileField;
139139
private final String platform;
140+
private final String automation;
140141

141-
AppiumAnnotations(Field field, String platform) {
142+
AppiumAnnotations(Field field, String platform, String automation) {
142143
super(field);
143144
mobileField = field;
144145
this.platform = String.valueOf(platform).
145146
toUpperCase().trim();
147+
this.automation = String.valueOf(automation);
146148
}
147149

148150
private static void checkDisallowedAnnotationPairs(Annotation a1,
@@ -161,14 +163,31 @@ private void assertValidAnnotations() {
161163
.getAnnotation(AndroidFindBys.class);
162164
AndroidFindAll androidFindAll = mobileField.
163165
getAnnotation(AndroidFindAll.class);
164-
166+
167+
SelendroidFindBy selendroidBy = mobileField
168+
.getAnnotation(SelendroidFindBy.class);
169+
SelendroidFindBys selendroidBys = mobileField
170+
.getAnnotation(SelendroidFindBys.class);
171+
SelendroidFindAll selendroidFindAll = mobileField.
172+
getAnnotation(SelendroidFindAll.class);
173+
165174
iOSFindBy iOSBy = mobileField.getAnnotation(iOSFindBy.class);
166175
iOSFindBys iOSBys = mobileField.getAnnotation(iOSFindBys.class);
167176
iOSFindAll iOSFindAll = mobileField.getAnnotation(iOSFindAll.class);
168177

169178
checkDisallowedAnnotationPairs(androidBy, androidBys);
179+
checkDisallowedAnnotationPairs(androidBy, selendroidBys);
170180
checkDisallowedAnnotationPairs(androidBy, androidFindAll);
181+
checkDisallowedAnnotationPairs(androidBy, selendroidFindAll);
171182
checkDisallowedAnnotationPairs(androidBys, androidFindAll);
183+
checkDisallowedAnnotationPairs(androidBys, selendroidFindAll);
184+
185+
checkDisallowedAnnotationPairs(selendroidBy, androidBys);
186+
checkDisallowedAnnotationPairs(selendroidBy, selendroidBys);
187+
checkDisallowedAnnotationPairs(selendroidBy, androidFindAll);
188+
checkDisallowedAnnotationPairs(selendroidBy, selendroidFindAll);
189+
checkDisallowedAnnotationPairs(selendroidBys, androidFindAll);
190+
checkDisallowedAnnotationPairs(selendroidBys, selendroidFindAll);
172191

173192
checkDisallowedAnnotationPairs(iOSBy, iOSBys);
174193
checkDisallowedAnnotationPairs(iOSBy, iOSFindAll);
@@ -248,12 +267,34 @@ private <T extends By> T getComplexMobileBy(Annotation[] annotations, Class<T> r
248267
public By buildBy() {
249268
assertValidAnnotations();
250269

270+
SelendroidFindBy selendroidBy = mobileField
271+
.getAnnotation(SelendroidFindBy.class);
272+
if (selendroidBy != null && ANDROID.toUpperCase().equals(platform) &&
273+
"Selendroid".equals(automation)) {
274+
return getMobileBy(selendroidBy, getFilledValue(selendroidBy));
275+
}
276+
277+
SelendroidFindBys selendroidBys = mobileField
278+
.getAnnotation(SelendroidFindBys.class);
279+
if (selendroidBy != null && ANDROID.toUpperCase().equals(platform) &&
280+
"Selendroid".equals(automation)) {
281+
return getMobileBy(selendroidBys, getFilledValue(selendroidBys));
282+
}
283+
284+
SelendroidFindAll selendroidAll = mobileField
285+
.getAnnotation(SelendroidFindAll.class);
286+
if (selendroidBy != null && ANDROID.toUpperCase().equals(platform) &&
287+
"Selendroid".equals(automation)) {
288+
return getMobileBy(selendroidAll, getFilledValue(selendroidAll));
289+
}
290+
291+
251292
AndroidFindBy androidBy = mobileField
252293
.getAnnotation(AndroidFindBy.class);
253294
if (androidBy != null && ANDROID.toUpperCase().equals(platform)) {
254295
return getMobileBy(androidBy, getFilledValue(androidBy));
255296
}
256-
297+
257298
AndroidFindBys androidBys = mobileField
258299
.getAnnotation(AndroidFindBys.class);
259300
if (androidBys != null && ANDROID.toUpperCase().equals(platform)) {
@@ -265,6 +306,7 @@ public By buildBy() {
265306
return getComplexMobileBy(androidFindAll.value(), ByAll.class);
266307
}
267308

309+
268310
iOSFindBy iOSBy = mobileField.getAnnotation(iOSFindBy.class);
269311
if (iOSBy != null && IOS.toUpperCase().equals(platform)) {
270312
return getMobileBy(iOSBy, getFilledValue(iOSBy));

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,12 @@ public List<WebElement> apply(By by) {
7171
.valueOf(((HasCapabilities) unpackWebDriverFromSearchContext())
7272
.getCapabilities().getCapability(
7373
MobileCapabilityType.PLATFORM_NAME));
74-
AppiumAnnotations annotations = new AppiumAnnotations(field, platform);
74+
String automation = String
75+
.valueOf(((HasCapabilities) unpackWebDriverFromSearchContext())
76+
.getCapabilities().getCapability(
77+
MobileCapabilityType.AUTOMATION_NAME));
78+
79+
AppiumAnnotations annotations = new AppiumAnnotations(field, platform, automation);
7580
this.timeOutContainer = timeOutContainer;
7681
shouldCache = annotations.isLookupCached();
7782
by = annotations.buildBy();
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package io.appium.java_client.pagefactory;
2+
3+
import java.lang.annotation.ElementType;
4+
import java.lang.annotation.Retention;
5+
import java.lang.annotation.RetentionPolicy;
6+
import java.lang.annotation.Target;
7+
8+
/**
9+
* Used to mark a field on a Page/Screen Object to indicate that lookup should use a series of {@link SelendroidFindBy} tags
10+
* It will then search for all elements that match any criteria. Note that elements
11+
* are not guaranteed to be in document order.
12+
*/
13+
@Retention(RetentionPolicy.RUNTIME)
14+
@Target({ElementType.FIELD, ElementType.TYPE})
15+
public @interface SelendroidFindAll {
16+
SelendroidFindBy[] value();
17+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package io.appium.java_client.pagefactory;
2+
3+
import java.lang.annotation.ElementType;
4+
import java.lang.annotation.Retention;
5+
import java.lang.annotation.RetentionPolicy;
6+
import java.lang.annotation.Target;
7+
8+
9+
/**
10+
* Used to mark a field on a Page Object to indicate an alternative mechanism for locating the
11+
* element or a list of elements. Used in conjunction with
12+
* {@link org.openqa.selenium.support.PageFactory}
13+
* this allows users to quickly and easily create PageObjects.
14+
* using Android UI selectors, accessibility, id, name, class name, tag and xpath
15+
*/
16+
@Retention(RetentionPolicy.RUNTIME)
17+
@Target({ElementType.FIELD, ElementType.TYPE})
18+
public @interface SelendroidFindBy {
19+
String uiAutomator() default "";
20+
String accessibility() default "";
21+
String id() default "";
22+
String name() default "";
23+
String className() default "";
24+
String tagName() default "";
25+
String xpath() default "";
26+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package io.appium.java_client.pagefactory;
2+
3+
import java.lang.annotation.ElementType;
4+
import java.lang.annotation.Retention;
5+
import java.lang.annotation.RetentionPolicy;
6+
import java.lang.annotation.Target;
7+
8+
/**
9+
* Used to mark a field on a Page Object to indicate that lookup should use a series of @SelendroidFindBy tags
10+
*/
11+
@Retention(RetentionPolicy.RUNTIME)
12+
@Target({ElementType.FIELD, ElementType.TYPE})
13+
public @interface SelendroidFindBys {
14+
SelendroidFindBy[] value();
15+
}

0 commit comments

Comments
 (0)