Skip to content

Commit b8fe9ac

Browse files
Merge pull request #538 from TikhomirovSergey/master
#471 FIX
2 parents 2fc8e1d + 4b36b51 commit b8fe9ac

23 files changed

+373
-134
lines changed

README.md

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ You can get it on [WIKI](https://github.com/appium/java-client/wiki)
8181
- API with default implementation. PR [#470](https://github.com/appium/java-client/pull/470)
8282
- Tools that provide _Page Object_ engines were redesigned. The migration to [repeatable annotations](http://docs.oracle.com/javase/tutorial/java/annotations/repeating.html). Details you can read there: [#497](https://github.com/appium/java-client/pull/497). [Documentation was synced as well](https://github.com/appium/java-client/blob/master/docs/Page-objects.md#also-it-is-possible-to-define-chained-or-any-possible-locators).
8383
- **[MAJOR ENHANCEMENT]**: Migration from Maven to Gradle. Feature request is [#214](https://github.com/appium/java-client/issues/214). Fixes: [#442](https://github.com/appium/java-client/pull/442), [#465](https://github.com/appium/java-client/pull/465).
84-
- **[MAJOR ENHANCEMENT]****[MAJOR REFACTORING]**. Non-abstract **AppiumDriver**:
84+
- **[MAJOR ENHANCEMENT]** **[MAJOR REFACTORING]**. Non-abstract **AppiumDriver**:
8585
- Now the `io.appium.java_client.AppiumDriver` can use an instance of any `io.appium.java_client.MobileBy` subclass for the searching. It should work as expected when current session supports the given selector. It will throw `org.openqa.selenium.WebDriverException` otherwise. [#462](https://github.com/appium/java-client/pull/462)
8686
- The new interface `io.appium.java_client.FindsByFluentSelector` was added. [#462](https://github.com/appium/java-client/pull/462)
8787
- API was redesigned:
@@ -129,22 +129,29 @@ You can get it on [WIKI](https://github.com/appium/java-client/wiki)
129129
- constructors of 'AppiumDriver' were re-designed.
130130
- constructors of 'AndroidDriver' were re-designed.
131131
- constructors of 'IOSDriver' were re-designed.
132-
133-
_The work is not finished yet._
134-
132+
133+
- **[MAJOR ENHANCEMENT]** Windows automation. Epic [#471](https://github.com/appium/java-client/issues/471)
134+
- The new interface `io.appium.java_client.FindsByWindowsAutomation` was added. [#462](https://github.com/appium/java-client/pull/462). With [@jonstoneman](https://github.com/jonstoneman) 's authorship.
135+
- The new selector strategy `io.appium.java_client.MobileBy.ByWindowsAutomation` was added. [#462](https://github.com/appium/java-client/pull/462). With [@jonstoneman](https://github.com/jonstoneman) 's authorship.
136+
- `io.appium.java_client.windows.WindowsDriver` was designed. [#538](https://github.com/appium/java-client/pull/538)
137+
- `io.appium.java_client.windows.WindowsElement` was designed. [#538](https://github.com/appium/java-client/pull/538)
138+
- `io.appium.java_client.windows.WindowsKeyCode ` was added. [#538](https://github.com/appium/java-client/pull/538)
139+
- Page object tools were updated [#538](https://github.com/appium/java-client/pull/538)
140+
- the `io.appium.java_client.pagefactory.WindowsFindBy` annotation was added.
141+
- `io.appium.java_client.pagefactory.AppiumFieldDecorator` and supporting tools were actualized.
142+
135143
- **[MAJOR ENHANCEMENT]**: The new interface `io.appium.java_client.FindsByIosNSPredicate` was added. [#462](https://github.com/appium/java-client/pull/462). With [@rafael-chavez](https://github.com/rafael-chavez) 's authorship.
136144
It is implemented by `io.appium.java_client.ios.IOSDriver` and `io.appium.java_client.ios.IOSElement`.
137145
- **[MAJOR ENHANCEMENT]**: The new interface `io.appium.java_client.MobileBy.ByIosNsPredicate` was added. [#462](https://github.com/appium/java-client/pull/462). With [@rafael-chavez](https://github.com/rafael-chavez) 's authorship.
138-
- **[MAJOR ENHANCEMENT]**: The new interface `io.appium.java_client.FindsByWindowsAutomation` was added. [#462](https://github.com/appium/java-client/pull/462). With [@jonstoneman](https://github.com/jonstoneman) 's authorship.
139-
- **[MAJOR ENHANCEMENT]**: The new interface `io.appium.java_client.MobileBy.ByWindowsAutomation` was added. [#462](https://github.com/appium/java-client/pull/462). With [@jonstoneman](https://github.com/jonstoneman) 's authorship.
140146
- [ENHANCEMENT] Added the ability to set UiAutomator Congfigurator values. [#410](https://github.com/appium/java-client/pull/410).
141147
[#477](https://github.com/appium/java-client/pull/477).
142148
- **[UPDATE]** to Selenium 3.0. [#489](https://github.com/appium/java-client/pull/489)
143149
- [ENHANCEMENT]. Additional methods which perform device rotation were implemented. [#489](https://github.com/appium/java-client/pull/489). [#439](https://github.com/appium/java-client/pull/439). But it works for iOS in XCUIT mode and for Android in UIAutomator2 mode only. The feature request: [#7131](https://github.com/appium/appium/issues/7131)
144150
- [ENHANCEMENT]. TouchID Implementation (iOS Sim Only). Details: [#509](https://github.com/appium/java-client/pull/509)
145151
- [ENHANCEMENT]. The ability to use port, ip and log file as server arguments was provided. Feature request: [#521](https://github.com/appium/java-client/issues/521). Fixes: [#522](https://github.com/appium/java-client/issues/522), [#524](https://github.com/appium/java-client/issues/524).
146152
- [ENHANCEMENT]. The new interface ```io.appium.java_client.android.HasDeviceDetails``` was added. It is implemented by ```io.appium.java_client.android.AndroidDriver``` by default. [#518](https://github.com/appium/java-client/pull/518)
147-
- [ENHANCEMENT].New touch actions were added. ```io.appium.java_client.ios.IOSTouchAction#doubleTap(WebElement, int, int)``` and ```io.appium.java_client.ios.IOSTouchAction#doubleTap(WebElement)```. [#523](https://github.com/appium/java-client/pull/523), [#444](https://github.com/appium/java-client/pull/444)
153+
- [ENHANCEMENT]. New touch actions were added. ```io.appium.java_client.ios.IOSTouchAction#doubleTap(WebElement, int, int)``` and ```io.appium.java_client.ios.IOSTouchAction#doubleTap(WebElement)```. [#523](https://github.com/appium/java-client/pull/523), [#444](https://github.com/appium/java-client/pull/444)
154+
- [ENHANCEMENT]. All constructors declared by `io.appium.java_client.AppiumDriver` are public now.
148155
- [BUG FIX]: There was the issue when "@WithTimeout" was changing general timeout of the waiting for elements. Bug report: [#467](https://github.com/appium/java-client/issues/467). Fixes: [#468](https://github.com/appium/java-client/issues/468), [#469](https://github.com/appium/java-client/issues/469), [#480](https://github.com/appium/java-client/issues/480). Read: [supported-settings](https://github.com/appium/appium/blob/master/docs/en/advanced-concepts/settings.md#supported-settings)
149156
- Added the server flag `io.appium.java_client.service.local.flags.AndroidServerFlag#REBOOT`. [#476](https://github.com/appium/java-client/pull/476)
150157
- Added `io.appium.java_client.remote.AndroidMobileCapabilityType.APP_WAIT_DURATION ` capability. [#461](https://github.com/appium/java-client/pull/461)

src/main/java/io/appium/java_client/AppiumDriver.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public class AppiumDriver<T extends WebElement>
7979
* @param capabilities take a look
8080
* at {@link org.openqa.selenium.Capabilities}
8181
*/
82-
protected AppiumDriver(HttpCommandExecutor executor, Capabilities capabilities) {
82+
public AppiumDriver(HttpCommandExecutor executor, Capabilities capabilities) {
8383
super(executor, capabilities);
8484
this.executeMethod = new AppiumExecutionMethod(this);
8585
locationContext = new RemoteLocationContext(executeMethod);
@@ -335,7 +335,7 @@ public void zoom(int x, int y) {
335335
@Override public String getContext() {
336336
String contextName =
337337
String.valueOf(execute(DriverCommand.GET_CURRENT_CONTEXT_HANDLE).getValue());
338-
if (contextName.equals("null")) {
338+
if ("null".equalsIgnoreCase(contextName)) {
339339
return null;
340340
}
341341
return contextName;

src/main/java/io/appium/java_client/android/AndroidDriver.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public class AndroidDriver<T extends WebElement>
5959
* at {@link org.openqa.selenium.Capabilities}
6060
*/
6161
public AndroidDriver(HttpCommandExecutor executor, Capabilities capabilities) {
62-
super(executor, capabilities);
62+
super(executor, substituteMobilePlatform(capabilities, ANDROID_PLATFORM));
6363
}
6464

6565
/**

src/main/java/io/appium/java_client/internal/ElementMap.java

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@
2323
import io.appium.java_client.ios.IOSElement;
2424
import io.appium.java_client.remote.AutomationName;
2525
import io.appium.java_client.remote.MobilePlatform;
26+
import io.appium.java_client.windows.WindowsElement;
2627
import io.appium.java_client.youiengine.YouiEngineElement;
28+
import org.openqa.selenium.remote.RemoteWebElement;
2729

2830
import java.util.Map;
2931
import java.util.Optional;
@@ -34,7 +36,8 @@ public enum ElementMap {
3436
YOUI_ENGINE(AutomationName.YOUI_ENGINE.toLowerCase(), YouiEngineElement.class),
3537
IOS_XCUI_TEST(AutomationName.IOS_XCUI_TEST.toLowerCase(), IOSElement.class),
3638
ANDROID_UI_AUTOMATOR(MobilePlatform.ANDROID.toLowerCase(), AndroidElement.class),
37-
IOS_UI_AUTOMATION(MobilePlatform.IOS.toLowerCase(), IOSElement.class);
39+
IOS_UI_AUTOMATION(MobilePlatform.IOS.toLowerCase(), IOSElement.class),
40+
WINDOWS(MobilePlatform.WINDOWS, WindowsElement.class);
3841

3942

4043
private static final Map<String, ElementMap> mobileElementMap;
@@ -50,7 +53,7 @@ public enum ElementMap {
5053

5154

5255
private final String platformOrAutomation;
53-
private final Class<? extends MobileElement> elementClass;
56+
private final Class<? extends RemoteWebElement> elementClass;
5457

5558
private ElementMap(String platformOrAutomation, Class<? extends MobileElement> elementClass) {
5659
this.platformOrAutomation = platformOrAutomation;
@@ -61,7 +64,7 @@ public String getPlatformOrAutomation() {
6164
return platformOrAutomation;
6265
}
6366

64-
public Class<? extends MobileElement> getElementClass() {
67+
public Class<? extends RemoteWebElement> getElementClass() {
6568
return elementClass;
6669
}
6770

@@ -70,11 +73,12 @@ public Class<? extends MobileElement> getElementClass() {
7073
* @param automation automation name.
7174
* @return subclass of {@link io.appium.java_client.MobileElement} that convenient to current session details.
7275
*/
73-
public static Class<? extends MobileElement> getElementClass(String platform, String automation) {
74-
ElementMap element = Optional.ofNullable(mobileElementMap.get(automation))
75-
.orElse(mobileElementMap.get(platform));
76+
public static Class<? extends RemoteWebElement> getElementClass(String platform, String automation) {
77+
ElementMap element = Optional.ofNullable(mobileElementMap.get(String
78+
.valueOf(automation).toLowerCase().trim()))
79+
.orElse(mobileElementMap.get(String.valueOf(platform).toLowerCase().trim()));
7680
if (element == null) {
77-
return null;
81+
return RemoteWebElement.class;
7882
}
7983
return element.getElementClass();
8084
}

src/main/java/io/appium/java_client/internal/JsonToMobileElementConverter.java

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,9 @@
2222
import com.google.common.collect.Lists;
2323
import com.google.common.collect.Maps;
2424

25-
import io.appium.java_client.MobileElement;
26-
2725
import org.openqa.selenium.WebDriverException;
2826
import org.openqa.selenium.remote.RemoteWebDriver;
27+
import org.openqa.selenium.remote.RemoteWebElement;
2928
import org.openqa.selenium.remote.internal.JsonToWebElementConverter;
3029

3130
import java.lang.reflect.Constructor;
@@ -74,7 +73,7 @@ public Object apply(Object result) {
7473
if (result instanceof Map<?, ?>) {
7574
Map<?, ?> resultAsMap = (Map<?, ?>) result;
7675
if (resultAsMap.containsKey("ELEMENT")) {
77-
MobileElement element = newMobileElement();
76+
RemoteWebElement element = newMobileElement();
7877
element.setId(String.valueOf(resultAsMap.get("ELEMENT")));
7978
element.setFileDetector(driver.getFileDetector());
8079
return element;
@@ -93,19 +92,13 @@ public Object apply(Object result) {
9392
return result;
9493
}
9594

96-
protected MobileElement newMobileElement() {
97-
Class<? extends MobileElement> target =
95+
protected RemoteWebElement newMobileElement() {
96+
Class<? extends RemoteWebElement> target =
9897
getElementClass(platform, automation);
99-
100-
if (target == null) {
101-
throw new WebDriverException(new ClassNotFoundException("The class of mobile element is "
102-
+ "unknown for current session"));
103-
}
104-
10598
try {
106-
Constructor<? extends MobileElement> constructor = target.getDeclaredConstructor();
99+
Constructor<? extends RemoteWebElement> constructor = target.getDeclaredConstructor();
107100
constructor.setAccessible(true);
108-
MobileElement result = constructor.newInstance();
101+
RemoteWebElement result = constructor.newInstance();
109102
result.setParent(driver);
110103
return result;
111104
} catch (Exception e) {

src/main/java/io/appium/java_client/ios/IOSDriver.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public class IOSDriver<T extends WebElement>
6262
* at {@link org.openqa.selenium.Capabilities}
6363
*/
6464
public IOSDriver(HttpCommandExecutor executor, Capabilities capabilities) {
65-
super(executor, capabilities);
65+
super(executor, substituteMobilePlatform(capabilities, IOS_PLATFORM));
6666
}
6767

6868
/**

src/main/java/io/appium/java_client/pagefactory/AppiumElementLocator.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,11 @@
3939

4040
class AppiumElementLocator implements CacheableLocator {
4141

42-
final boolean shouldCache;
43-
final By by;
44-
final TimeOutDuration timeOutDuration;
42+
private final boolean shouldCache;
43+
private final By by;
44+
private final TimeOutDuration timeOutDuration;
4545
private final TimeOutDuration originalTimeOutDuration;
46-
final WebDriver originalWebDriver;
46+
private final WebDriver originalWebDriver;
4747
private final SearchContext searchContext;
4848
private final WaitingFunction waitingFunction;
4949
private WebElement cachedElement;

src/main/java/io/appium/java_client/pagefactory/AppiumFieldDecorator.java

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import io.appium.java_client.ios.IOSElement;
2929
import io.appium.java_client.pagefactory.bys.ContentType;
3030
import io.appium.java_client.pagefactory.locator.CacheableLocator;
31+
import io.appium.java_client.windows.WindowsElement;
3132
import org.openqa.selenium.SearchContext;
3233
import org.openqa.selenium.WebDriver;
3334
import org.openqa.selenium.WebElement;
@@ -43,7 +44,6 @@
4344
import java.util.ArrayList;
4445
import java.util.List;
4546
import java.util.Map;
46-
import java.util.Optional;
4747
import java.util.concurrent.TimeUnit;
4848

4949
/**
@@ -69,6 +69,7 @@ public class AppiumFieldDecorator implements FieldDecorator {
6969
add(TouchableElement.class);
7070
add(AndroidElement.class);
7171
add(IOSElement.class);
72+
add(WindowsElement.class);
7273
}
7374

7475
};
@@ -91,13 +92,7 @@ private static String extractSessionData(WebDriver driver, String parameter) {
9192
return null;
9293
}
9394

94-
Object parameterValue = HasSessionDetails.class.cast(driver).getSessionDetail(parameter);
95-
96-
if (parameterValue == null) {
97-
return null;
98-
}
99-
100-
return String.valueOf(parameterValue).toLowerCase();
95+
return String.valueOf(HasSessionDetails.class.cast(driver).getSessionDetail(parameter));
10196
}
10297

10398
public AppiumFieldDecorator(SearchContext context, long implicitlyWaitTimeOut,
@@ -147,15 +142,12 @@ protected List<WebElement> proxyForListLocator(ClassLoader ignored,
147142

148143
Type listType = ((ParameterizedType) genericType).getActualTypeArguments()[0];
149144

150-
boolean result = false;
151145
for (Class<? extends WebElement> webElementClass : availableElementClasses) {
152-
if (!webElementClass.equals(listType)) {
153-
continue;
146+
if (webElementClass.equals(listType)) {
147+
return true;
154148
}
155-
result = true;
156-
break;
157149
}
158-
return result;
150+
return false;
159151
}
160152
};
161153

@@ -235,14 +227,8 @@ private Object decorateWidget(Field field) {
235227
new WidgetInterceptor(locator, originalDriver, null, map, timeOutDuration));
236228
}
237229

238-
private Class<?> getTypeForProxy() {
239-
Optional<Class<?>> optionalClass =
240-
Optional.ofNullable(getElementClass(platform, automation));
241-
return optionalClass.orElse(RemoteWebElement.class);
242-
}
243-
244230
private WebElement proxyForAnElement(ElementLocator locator) {
245231
ElementInterceptor elementInterceptor = new ElementInterceptor(locator, originalDriver);
246-
return (WebElement) getEnhancedProxy(getTypeForProxy(), elementInterceptor);
232+
return getEnhancedProxy(getElementClass(platform, automation), elementInterceptor);
247233
}
248234
}

0 commit comments

Comments
 (0)