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
@@ -1,14 +1,17 @@
package io.appium.java_client.pagefactory;

import io.appium.java_client.AppiumDriver;
import io.appium.java_client.MobileElement;
import io.appium.java_client.TouchableElement;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;
import io.appium.java_client.ios.IOSDriver;
import io.appium.java_client.ios.IOSElement;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.*;
import java.util.concurrent.TimeUnit;

import org.openqa.selenium.SearchContext;
Expand Down Expand Up @@ -37,24 +40,38 @@ public class AppiumFieldDecorator implements FieldDecorator, ResetsImplicitlyWai
add(WebElement.class);
add(RemoteWebElement.class);
add(MobileElement.class);
add(TouchableElement.class);
add(AndroidElement.class);
add(IOSElement.class);
}

};

private final static Map<Class<? extends SearchContext>, Class<? extends WebElement>> elementRuleMap =
new HashMap<Class<? extends SearchContext>, Class<? extends WebElement>>(){
private static final long serialVersionUID = 1L;
{
put(AndroidDriver.class, AndroidElement.class);
put(AndroidElement.class, AndroidElement.class);
put(IOSDriver.class, IOSElement.class);
put(IOSElement.class, IOSElement.class);
}
};

private final AppiumElementLocatorFactory factory;

private final SearchContext context;
public static long DEFAULT_IMPLICITLY_WAIT_TIMEOUT = 1;

public static TimeUnit DEFAULT_TIMEUNIT = TimeUnit.SECONDS;

public AppiumFieldDecorator(SearchContext context, long implicitlyWaitTimeOut, TimeUnit timeUnit) {
factory = new AppiumElementLocatorFactory(context, implicitlyWaitTimeOut, timeUnit);
this.context = context;
factory = new AppiumElementLocatorFactory(this.context, implicitlyWaitTimeOut, timeUnit);
}

public AppiumFieldDecorator(SearchContext context) {
factory = new AppiumElementLocatorFactory(context);
this.context = context;
factory = new AppiumElementLocatorFactory(this.context);
}

public Object decorate(ClassLoader ignored, Field field) {
Expand All @@ -68,7 +85,7 @@ public Object decorate(ClassLoader ignored, Field field) {
}

if (WebElement.class.isAssignableFrom(field.getType())) {
return proxyForLocator(field, locator);
return proxyForLocator(locator);
} else if (List.class.isAssignableFrom(field.getType())) {
return proxyForListLocator(locator);
} else {
Expand Down Expand Up @@ -107,13 +124,22 @@ private boolean isDecoratableList(Field field) {
//DefaultElementLocator has an issue :)
}

private Object proxyForLocator(Field field, ElementLocator locator) {
Class<?> type = field.getType();
if (type.equals(WebElement.class)){
type = RemoteWebElement.class;
}
private Class<?> getTypeForProxy(){
Class<?> contextClass = context.getClass();
Iterable<Map.Entry<Class<? extends SearchContext>, Class<? extends WebElement>>> rules = elementRuleMap.entrySet();
Iterator<Map.Entry<Class<? extends SearchContext>, Class<? extends WebElement>>> iterator = rules.iterator();
while (iterator.hasNext()){ //it will return MobileElement subclass when here is something
//that extends AppiumDriver or MobileElement
Map.Entry<Class<? extends SearchContext>, Class<? extends WebElement>> e = iterator.next();
if (e.getKey().isAssignableFrom(contextClass))
return e.getValue();
} //it is compatible with desktop browser. So at this case it returns RemoteWebElement.class
return RemoteWebElement.class;
}

private Object proxyForLocator(ElementLocator locator) {
ElementInterceptor elementInterceptor = new ElementInterceptor(locator);
return ProxyFactory.getEnhancedProxy(type,
return ProxyFactory.getEnhancedProxy(getTypeForProxy(),
elementInterceptor);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.appium.java_client.pagefactory_tests;

import io.appium.java_client.MobileElement;
import io.appium.java_client.TouchableElement;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;
import io.appium.java_client.pagefactory.AndroidFindAll;
Expand All @@ -17,6 +18,7 @@
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.apache.xpath.operations.And;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
Expand Down Expand Up @@ -76,6 +78,9 @@ public class AndroidPageObjectTest {
@iOSFindBy(xpath = "//someElement")})
private List<WebElement> chainAndroidOrIOSUIAutomatorViews;

@AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/text1\")")
private List<TouchableElement> touchabletextVieWs;

@FindBy(id = "android:id/text1")
private WebElement textView;

Expand Down Expand Up @@ -153,6 +158,9 @@ public class AndroidPageObjectTest {
@AndroidFindBy(id = "android:id/text1")
@SelendroidFindBy(id = "Invalid Identifier")
private WebElement textAndroidId;

@AndroidFindBy(uiAutomator = "new UiSelector().resourceId(\"android:id/text1\")")
private TouchableElement touchabletextVieW;

@Before
public void setUp() throws Exception {
Expand Down Expand Up @@ -320,5 +328,23 @@ public void findAllElementsTest(){
@Test
public void findByAndroidAnnotationOnlyTest(){
Assert.assertNotEquals(null, textAndroidId.getAttribute("text"));
}
}

@Test
public void isTouchableElement(){
Assert.assertNotEquals(null, touchabletextVieW.getAttribute("text"));
}

@Test
public void areTouchableElements(){
Assert.assertNotEquals(0, touchabletextVieWs.size());
}

@Test
public void isTheFieldAndroidElement(){
AndroidElement androidElement = (AndroidElement) mobiletextVieW; //declared as MobileElement
androidElement = (AndroidElement) androidTextView; //declared as WedElement
androidElement = (AndroidElement) remotetextVieW; //declared as RemoteWedElement
androidElement = (AndroidElement) touchabletextVieW; //declared as TouchABLEElement
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package io.appium.java_client.pagefactory_tests;

import io.appium.java_client.MobileElement;
import io.appium.java_client.TouchableElement;
import io.appium.java_client.android.AndroidElement;
import io.appium.java_client.ios.IOSDriver;
import io.appium.java_client.ios.IOSElement;
import io.appium.java_client.pagefactory.AndroidFindBy;
Expand Down Expand Up @@ -80,6 +82,12 @@ public class iOSPageObjectTest {
@iOSFindBy(uiAutomator = ".elements()[0]")
private MobileElement mobileButton;

@iOSFindBy(uiAutomator = ".elements()[0]")
private TouchableElement touchableButton;

@iOSFindBy(uiAutomator = ".elements()[0]")
private List<TouchableElement> touchableButtons;

@FindBy(className = "UIAButton")
private MobileElement mobiletFindBy_Button;

Expand Down Expand Up @@ -253,4 +261,22 @@ public void findAllElementsTest(){
public void findAllElementTest(){
Assert.assertNotEquals(null, findAllElement.getText());
}

@Test
public void isTouchAbleElement(){
Assert.assertNotEquals(null, touchableButton.getText());
}

@Test
public void areTouchAbleElements(){
Assert.assertNotEquals(0, touchableButtons.size());
}

@Test
public void isTheFieldIOSElement(){
IOSElement iOSElement = (IOSElement) mobileButton; //declared as MobileElement
iOSElement = (IOSElement) iosUIAutomatorButton; //declared as WedElement
iOSElement = (IOSElement) remotetextVieW; //declared as RemoteWedElement
iOSElement = (IOSElement) touchableButton; //declared as TouchABLEElement
}
}