diff --git a/src/main/java/io/qameta/htmlelements/annotation/FindBy.java b/src/main/java/io/qameta/htmlelements/annotation/FindBy.java index c87366a..5a61ebd 100644 --- a/src/main/java/io/qameta/htmlelements/annotation/FindBy.java +++ b/src/main/java/io/qameta/htmlelements/annotation/FindBy.java @@ -29,7 +29,10 @@ @HandleWith(FindBy.Extension.class) public @interface FindBy { - String value(); + String value() default ""; + String xpath() default ""; + String css() default ""; + String id() default ""; class Extension implements MethodHandler { @@ -39,7 +42,7 @@ public Object handle(Context context, Object proxy, Method method, Object[] args // html element proxy (recurse) if (method.isAnnotationPresent(FindBy.class) && WebElement.class.isAssignableFrom(proxyClass)) { - String selector = ReflectionUtils.getSelector(method, args); + By selector = ReflectionUtils.getSelector(method, args); Context childContext = context.newChildContext(method, method.getReturnType()); childContext.getRegistry().getExtensions(ContextEnricher.class) @@ -47,14 +50,14 @@ public Object handle(Context context, Object proxy, Method method, Object[] args return createProxy( method.getReturnType(), childContext, - () -> ((SearchContext) proxy).findElement(By.xpath(selector)), + () -> ((SearchContext) proxy).findElement(selector), WebElement.class, Locatable.class ); } // html element list proxy (recurse) if (method.isAnnotationPresent(FindBy.class) && List.class.isAssignableFrom(method.getReturnType())) { - String selector = ReflectionUtils.getSelector(method, args); + By selector = ReflectionUtils.getSelector(method, args); Context childContext = context.newChildContext(method, method.getReturnType()); childContext.getRegistry().getExtensions(ContextEnricher.class) @@ -63,7 +66,7 @@ public Object handle(Context context, Object proxy, Method method, Object[] args method.getReturnType(), childContext, () -> { - List originalElements = ((SearchContext) proxy).findElements(By.xpath(selector)); + List originalElements = ((SearchContext) proxy).findElements(selector); Type methodReturnType = ((ParameterizedType) method .getGenericReturnType()).getActualTypeArguments()[0]; return (List) originalElements.stream() diff --git a/src/main/java/io/qameta/htmlelements/extension/SelectorProvider.java b/src/main/java/io/qameta/htmlelements/extension/SelectorProvider.java index 414f558..e77ccf9 100644 --- a/src/main/java/io/qameta/htmlelements/extension/SelectorProvider.java +++ b/src/main/java/io/qameta/htmlelements/extension/SelectorProvider.java @@ -2,6 +2,8 @@ import io.qameta.htmlelements.annotation.FindBy; import io.qameta.htmlelements.context.Context; +import io.qameta.htmlelements.util.ReflectionUtils; +import org.openqa.selenium.By; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -22,8 +24,8 @@ class Extension implements ContextEnricher, MethodHandler { @Override public void enrich(Context context, Method method, Object[] args) { - String selector = method.getAnnotation(FindBy.class).value(); - context.getStore().put(SELECTOR_KEY, selector); + By selector = ReflectionUtils.getSelector(method, args); + context.getStore().put(SELECTOR_KEY, selector.toString()); } @Override diff --git a/src/main/java/io/qameta/htmlelements/util/ReflectionUtils.java b/src/main/java/io/qameta/htmlelements/util/ReflectionUtils.java index 4277148..abcf61b 100644 --- a/src/main/java/io/qameta/htmlelements/util/ReflectionUtils.java +++ b/src/main/java/io/qameta/htmlelements/util/ReflectionUtils.java @@ -7,6 +7,7 @@ import org.apache.commons.lang3.ClassUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.reflect.ConstructorUtils; +import org.openqa.selenium.By; import java.lang.reflect.Method; import java.util.ArrayList; @@ -14,6 +15,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -21,6 +23,9 @@ public class ReflectionUtils { + private static final int UNIQ_LOCATOR_COUNT = 1; + + public static T newInstance(Class clazz) { try { return ConstructorUtils.invokeConstructor(clazz); @@ -70,13 +75,51 @@ public static String getDescription(Class clazz) { return splitCamelCase(clazz.getSimpleName()); } - public static String getSelector(Method method, Object[] args) { - Map parameters = getParameters(method, args); - String selector = method.getAnnotation(FindBy.class).value(); - for (String key : parameters.keySet()) { - selector = selector.replaceAll("\\{\\{ " + key + " \\}\\}", parameters.get(key)); + public static By getSelector(Method method, Object[] args) { + Function replaceParam= locator->{ + Map parameters = getParameters(method, args); + for (String key : parameters.keySet()) { + locator = locator.replaceAll("\\{\\{" + key + "\\}\\}", parameters.get(key)); + } + return locator; + + }; + By by= null; + String locator; + FindBy findBy=method.getAnnotation(FindBy.class); + List locators = new ArrayList<>(); + //default xpath + if(!findBy.value().isEmpty()) { + locator=replaceParam.apply(findBy.value()); + by = By.xpath(locator); + locators.add(locator); + } + + //xpath + if(!findBy.xpath().isEmpty()) { + locator=replaceParam.apply(findBy.xpath()); + by = By.xpath(locator); + locators.add(locator); + } + //css + if(!findBy.css().isEmpty()) { + locator=replaceParam.apply(findBy.css()); + by = By.cssSelector(locator); + locators.add(locator); + } + //id + if(!findBy.id().isEmpty()) { + locator=replaceParam.apply(findBy.id()); + by = By.id(locator); + locators.add(locator); + } + + if (locators.size() != UNIQ_LOCATOR_COUNT) { + throw new IllegalArgumentException( + String.format("You must specify at most one location strategy. Number found: %d (%s)", + locators.size(), locators.toString())); } - return selector; + return by; } public static String getDescription(Method method, Object[] args) { @@ -84,7 +127,7 @@ public static String getDescription(Method method, Object[] args) { Map parameters = getParameters(method, args); String name = method.getAnnotation(Description.class).value(); for (String key : parameters.keySet()) { - name = name.replaceAll("\\{\\{ " + key + " \\}\\}", parameters.get(key)); + name = name.replaceAll("\\{\\{" + key + "\\}\\}", parameters.get(key)); } return name; } else {