Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
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 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})
public @interface AndroidFindAll {
AndroidFindBy[] value();
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import io.appium.java_client.MobileBy;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
Expand All @@ -12,6 +13,7 @@

import org.openqa.selenium.By;
import org.openqa.selenium.support.pagefactory.Annotations;
import org.openqa.selenium.support.pagefactory.ByAll;
import org.openqa.selenium.support.pagefactory.ByChained;

class AppiumAnnotations extends Annotations{
Expand Down Expand Up @@ -143,26 +145,34 @@ By getBy(Annotation annotation) {
toUpperCase().trim();
}

private static void checkDisallowedAnnotationPairs(Annotation a1,
Annotation a2) 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");
}
}

private void assertValidAnnotations() {
AndroidFindBy androidBy = mobileField
.getAnnotation(AndroidFindBy.class);
AndroidFindBys androidBys = mobileField
.getAnnotation(AndroidFindBys.class);
AndroidFindAll androidFindAll = mobileField.
getAnnotation(AndroidFindAll.class);

iOSFindBy iOSBy = mobileField.getAnnotation(iOSFindBy.class);
iOSFindBys iOSBys = mobileField.getAnnotation(iOSFindBys.class);

if (androidBy != null && androidBys != null) {
throw new IllegalArgumentException(
"If you use a '@AndroidFindBy' annotation, "
+ "you must not also use a '@AndroidFindBys' annotation");
}

if (iOSBy != null && iOSBys != null) {
throw new IllegalArgumentException(
"If you use a '@iOSFindBy' annotation, "
+ "you must not also use a '@iOSFindBys' annotation");
}
iOSFindAll iOSFindAll = mobileField.getAnnotation(iOSFindAll.class);

checkDisallowedAnnotationPairs(androidBy, androidBys);
checkDisallowedAnnotationPairs(androidBy, androidFindAll);
checkDisallowedAnnotationPairs(androidBys, androidFindAll);

checkDisallowedAnnotationPairs(iOSBy, iOSBys);
checkDisallowedAnnotationPairs(iOSBy, iOSFindAll);
checkDisallowedAnnotationPairs(iOSBys, iOSFindAll);
}

private static Method[] prepareAnnotationMethods(
Expand Down Expand Up @@ -217,14 +227,21 @@ private By getMobileBy(Annotation annotation, String valueName) {
+ ": There is an unknown strategy " + valueName);
}

private By getChainedMobileBy(Annotation[] annotations) {
@SuppressWarnings("unchecked")
private <T extends By> T getComplexMobileBy(Annotation[] annotations, Class<T> requiredByClass) {
;
By[] byArray = new By[annotations.length];
for (int i = 0; i < annotations.length; i++) {
byArray[i] = getMobileBy(annotations[i],
getFilledValue(annotations[i]));
}
return new ByChained(byArray);
try {
Constructor<?> c = requiredByClass.getConstructor(By[].class);
Object[] values = new Object[]{byArray};
return (T) c.newInstance(values);
} catch (Exception e) {
throw new RuntimeException(e);
}
}

@Override
Expand All @@ -240,7 +257,12 @@ public By buildBy() {
AndroidFindBys androidBys = mobileField
.getAnnotation(AndroidFindBys.class);
if (androidBys != null && ANDROID.toUpperCase().equals(platform)) {
return getChainedMobileBy(androidBys.value());
return getComplexMobileBy(androidBys.value(), ByChained.class);
}

AndroidFindAll androidFindAll = mobileField.getAnnotation(AndroidFindAll.class);
if (androidFindAll != null && ANDROID.toUpperCase().equals(platform)) {
return getComplexMobileBy(androidFindAll.value(), ByAll.class);
}

iOSFindBy iOSBy = mobileField.getAnnotation(iOSFindBy.class);
Expand All @@ -250,8 +272,13 @@ public By buildBy() {

iOSFindBys iOSBys = mobileField.getAnnotation(iOSFindBys.class);
if (iOSBys != null && IOS.toUpperCase().equals(platform)) {
return getChainedMobileBy(iOSBys.value());
return getComplexMobileBy(iOSBys.value(), ByChained.class);
}

iOSFindAll iOSFindAll = mobileField.getAnnotation(iOSFindAll.class);
if (iOSFindAll != null && IOS.toUpperCase().equals(platform)) {
return getComplexMobileBy(iOSFindAll.value(), ByAll.class);
}

return super.buildBy();
}
Expand Down
Loading