SeleniumFieldDecorator added to fix an issue with the creation of the

proxy for annotated fields of the type List<WebElement>. The new class
is needed, since Seleniums default implementation performs a check
regarding valid annotations for this kind of fields, which is already
done in our ElementLocatorFactory.
This commit is contained in:
D049941 committed 2013-11-30 12:09:38 +01:00
1 parent a1c301ed87
commit 66e4f86c1a
2 files changed
+89 -4

No files matched your search

@@ -0,0 +1,87 @@
package com.sap.sailing.selenium.core;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Proxy;
import java.lang.reflect.Type;
import java.util.List;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.internal.Locatable;
import org.openqa.selenium.internal.WrapsElement;
import org.openqa.selenium.support.pagefactory.ElementLocator;
import org.openqa.selenium.support.pagefactory.ElementLocatorFactory;
import org.openqa.selenium.support.pagefactory.FieldDecorator;
import org.openqa.selenium.support.pagefactory.internal.LocatingElementHandler;
import org.openqa.selenium.support.pagefactory.internal.LocatingElementListHandler;
public class SeleniumFieldDecorator implements FieldDecorator {
private ElementLocatorFactory factory;
public SeleniumFieldDecorator(ElementLocatorFactory factory) {
this.factory = factory;
}
@Override
public Object decorate(ClassLoader loader, Field field) {
ElementLocator locator = this.factory.createLocator(field);
if (locator == null) {
return null;
}
if (isDecoratableField(field)) {
return proxyForElementLocator(loader, locator);
}
if (isDecoratableList(field)) {
return proxyForElementsLocator(loader, locator);
}
return null;
}
private boolean isDecoratableField(Field field) {
return WebElement.class.isAssignableFrom(field.getType());
}
private boolean isDecoratableList(Field field) {
if (!List.class.isAssignableFrom(field.getType())) {
return false;
}
// Type erasure in Java isn't complete. Attempt to discover the generic type of the list.
Type genericType = field.getGenericType();
if (!(genericType instanceof ParameterizedType)) {
return false;
}
Type listType = ((ParameterizedType) genericType).getActualTypeArguments()[0];
if (!WebElement.class.equals(listType)) {
return false;
}
return true;
}
private Object proxyForElementLocator(ClassLoader loader, ElementLocator locator) {
InvocationHandler handler = new LocatingElementHandler(locator);
Object proxy = Proxy.newProxyInstance( loader, new Class[] {WebElement.class, WrapsElement.class, Locatable.class}, handler);
return proxy;
}
private Object proxyForElementsLocator(ClassLoader loader, ElementLocator locator) {
InvocationHandler handler = new LocatingElementListHandler(locator);
Object proxy = Proxy.newProxyInstance(loader, new Class[] {List.class}, handler);
return proxy;
}
}
@@ -4,15 +4,12 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.SearchContext;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.FluentWait;
import com.sap.sailing.selenium.core.AjaxCallsComplete;
@@ -20,6 +17,7 @@ import com.sap.sailing.selenium.core.BySeleniumId;
import com.sap.sailing.selenium.core.FindBy;
import com.sap.sailing.selenium.core.FindBys;
import com.sap.sailing.selenium.core.SeleniumElementLocatorFactory;
import com.sap.sailing.selenium.core.SeleniumFieldDecorator;
/**
* <p>Within a web app's UI there are areas that tests interact with. A page object simply models these as objects
@@ -241,7 +239,7 @@ public class PageObject {
* the default implementation.</p>
*/
protected void initElements() {
PageFactory.initElements(new SeleniumElementLocatorFactory(this.context, getPageLoadTimeOut()), this);
PageFactory.initElements(new SeleniumFieldDecorator(new SeleniumElementLocatorFactory(this.context, getPageLoadTimeOut())), this);
}
/**