mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-18 18:20:58 +00:00
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:
1 parent
a1c301ed87
commit
66e4f86c1a
2 files changed
+89
-4
No files matched your search
+87
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
+2
-4
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in new issue
Block a user