From fb9885fc1e65895069483eb99cf361e4d1015f56 Mon Sep 17 00:00:00 2001 From: TikhomirovSergey Date: Tue, 23 Aug 2016 13:41:47 +0300 Subject: [PATCH 1/4] #455 fix. Re-implementation of the current searching. - the new interface FindsByFluentSelector was added. - the new enum MobileSelector was added. - the refactoring of the MobileBy. - the refactoring of the IOSDriver and IOSElement. - the refactoring of the AndroidDriver and AndroidElement. - API was changed. --- .../DefaultGenericMobileDriver.java | 4 +- .../DefaultGenericMobileElement.java | 4 +- .../java_client/FindsByFluentSelector.java | 53 ++++++ .../java/io/appium/java_client/MobileBy.java | 169 ++++++++++++++++-- .../io/appium/java_client/MobileDriver.java | 2 +- .../io/appium/java_client/MobileSelector.java | 33 ++++ .../appium/java_client/TouchableElement.java | 2 +- .../java_client/android/AndroidDriver.java | 5 +- .../java_client/android/AndroidElement.java | 5 +- .../io/appium/java_client/ios/IOSDriver.java | 5 +- .../io/appium/java_client/ios/IOSElement.java | 5 +- 11 files changed, 254 insertions(+), 33 deletions(-) create mode 100644 src/main/java/io/appium/java_client/FindsByFluentSelector.java create mode 100644 src/main/java/io/appium/java_client/MobileSelector.java diff --git a/src/main/java/io/appium/java_client/DefaultGenericMobileDriver.java b/src/main/java/io/appium/java_client/DefaultGenericMobileDriver.java index 19555f105..6d1ea9a03 100644 --- a/src/main/java/io/appium/java_client/DefaultGenericMobileDriver.java +++ b/src/main/java/io/appium/java_client/DefaultGenericMobileDriver.java @@ -142,14 +142,14 @@ public List findElementsByXPath(String using) { * @throws WebDriverException This method is not applicable with browser/webview UI. */ @Override public T findElementByAccessibilityId(String using) throws WebDriverException { - return (T) findElement("accessibility id", using); + return (T) findElement(MobileSelector.ACCESSIBILITY.toString(), using); } /** * @throws WebDriverException This method is not applicable with browser/webview UI. */ @Override public List findElementsByAccessibilityId(String using) throws WebDriverException { - return (List) findElements("accessibility id", using); + return (List) findElements(MobileSelector.ACCESSIBILITY.toString(), using); } /** diff --git a/src/main/java/io/appium/java_client/DefaultGenericMobileElement.java b/src/main/java/io/appium/java_client/DefaultGenericMobileElement.java index 88884e405..87adcd227 100644 --- a/src/main/java/io/appium/java_client/DefaultGenericMobileElement.java +++ b/src/main/java/io/appium/java_client/DefaultGenericMobileElement.java @@ -132,11 +132,11 @@ public List findElementsByXPath(String using) { } @Override public T findElementByAccessibilityId(String using) { - return (T) findElement("accessibility id", using); + return (T) findElement(MobileSelector.ACCESSIBILITY.toString(), using); } @Override public List findElementsByAccessibilityId(String using) { - return findElements("accessibility id", using); + return findElements(MobileSelector.ACCESSIBILITY.toString(), using); } /** diff --git a/src/main/java/io/appium/java_client/FindsByFluentSelector.java b/src/main/java/io/appium/java_client/FindsByFluentSelector.java new file mode 100644 index 000000000..3c7459389 --- /dev/null +++ b/src/main/java/io/appium/java_client/FindsByFluentSelector.java @@ -0,0 +1,53 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.appium.java_client; + +import org.openqa.selenium.NoSuchElementException; +import org.openqa.selenium.WebDriverException; +import org.openqa.selenium.WebElement; + +import java.util.List; + +public interface FindsByFluentSelector { + + /** + * Method performs the searching for a single element by some selector defined by string + * and value of the given selector + * + * @param by is a string selector + * @param using is a value of the given selector + * @return the first found element + * + * @throws WebDriverException when current session doesn't support the given selector or when + * value of the selector is not consistent. + * @throws NoSuchElementException when no one element is found + */ + T findElement(String by, String using) throws WebDriverException, NoSuchElementException; + + /** + * Method performs the searching for a list of elements by some selector defined by string + * and value of the given selector + * + * @param by is a string selector + * @param using is a value of the given selector + * @return a list of elements + * + * @throws WebDriverException when current session doesn't support the given selector or when + * value of the selector is not consistent. + */ + List findElements(String by, String using) throws WebDriverException; +} diff --git a/src/main/java/io/appium/java_client/MobileBy.java b/src/main/java/io/appium/java_client/MobileBy.java index 7ece7110c..5c9ad4975 100644 --- a/src/main/java/io/appium/java_client/MobileBy.java +++ b/src/main/java/io/appium/java_client/MobileBy.java @@ -19,6 +19,7 @@ import org.apache.commons.lang3.StringUtils; import org.openqa.selenium.By; import org.openqa.selenium.SearchContext; +import org.openqa.selenium.WebDriverException; import org.openqa.selenium.WebElement; import java.io.Serializable; @@ -27,19 +28,41 @@ @SuppressWarnings("serial") public abstract class MobileBy extends By { + private static final String ERROR_TEXT = "The class %s of the given context " + + "doesn't implement %s nor %s. Sorry. It is impossible to find something."; + private final String locatorString; + private final MobileSelector selector; + + private static IllegalArgumentException formIllegalArgumentException(Class givenClass, + Class class1, Class class2) { + return new IllegalArgumentException(String.format(ERROR_TEXT, givenClass.getCanonicalName(), + class1.getCanonicalName(), class2.getCanonicalName())); + } - protected MobileBy(String locatorString) { + protected MobileBy(MobileSelector selector, String locatorString) { if (StringUtils.isBlank(locatorString)) { throw new IllegalArgumentException("Must supply a not empty locator value."); } this.locatorString = locatorString; + this.selector = selector; } protected String getLocatorString() { return locatorString; } + @SuppressWarnings("unchecked") + @Override public List findElements(SearchContext context) { + return (List) ((FindsByFluentSelector) context) + .findElements(selector.toString(), getLocatorString()); + } + + @Override public WebElement findElement(SearchContext context) { + return ((FindsByFluentSelector) context) + .findElement(selector.toString(), getLocatorString()); + } + /** * Read https://developer.apple.com/library/tvos/documentation/DeveloperTools/ * Conceptual/InstrumentsUserGuide/UIAutomation.html @@ -77,19 +100,55 @@ public static By AccessibilityId(final String accessibilityId) { public static class ByIosUIAutomation extends MobileBy implements Serializable { public ByIosUIAutomation(String iOSAutomationText) { - super(iOSAutomationText); + super(MobileSelector.IOS_UI_AUTOMATION, iOSAutomationText); } + /** + * @throws WebDriverException when current session doesn't support the given selector or when + * value of the selector is not consistent. + * @throws IllegalArgumentException when it is impossible to find something on the given + * {@link SearchContext} instance + */ @SuppressWarnings("unchecked") @Override - public List findElements(SearchContext context) { - return (List) ((FindsByIosUIAutomation) context) + public List findElements(SearchContext context) throws WebDriverException, + IllegalArgumentException { + Class contextClass = context.getClass(); + + if (FindsByIosUIAutomation.class.isAssignableFrom(contextClass)) { + return FindsByIosUIAutomation.class.cast(context) .findElementsByIosUIAutomation(getLocatorString()); + } + + if (FindsByFluentSelector.class.isAssignableFrom(context.getClass())) { + return super.findElements(context); + } + + throw formIllegalArgumentException(contextClass, FindsByIosUIAutomation.class, + FindsByFluentSelector.class); } - @Override public WebElement findElement(SearchContext context) { - return ((FindsByIosUIAutomation) context) - .findElementByIosUIAutomation(getLocatorString()); + /** + * @throws WebDriverException when current session doesn't support the given selector or when + * value of the selector is not consistent. + * @throws IllegalArgumentException when it is impossible to find something on the given + * {@link SearchContext} instance + */ + @Override public WebElement findElement(SearchContext context) throws WebDriverException, + IllegalArgumentException { + Class contextClass = context.getClass(); + + if (FindsByIosUIAutomation.class.isAssignableFrom(contextClass)) { + return ((FindsByIosUIAutomation) context) + .findElementByIosUIAutomation(getLocatorString()); + } + + if (FindsByFluentSelector.class.isAssignableFrom(context.getClass())) { + return super.findElement(context); + } + + throw formIllegalArgumentException(contextClass, FindsByIosUIAutomation.class, + FindsByFluentSelector.class); } @Override public String toString() { @@ -102,19 +161,55 @@ public static class ByAndroidUIAutomator extends MobileBy implements Serializabl public ByAndroidUIAutomator(String uiautomatorText) { - super(uiautomatorText); + super(MobileSelector.ANDROID_UI_AUTOMATOR, uiautomatorText); } + /** + * @throws WebDriverException when current session doesn't support the given selector or when + * value of the selector is not consistent. + * @throws IllegalArgumentException when it is impossible to find something on the given + * {@link SearchContext} instance + */ @SuppressWarnings("unchecked") @Override - public List findElements(SearchContext context) { - return (List) ((FindsByAndroidUIAutomator) context) + public List findElements(SearchContext context) throws WebDriverException, + IllegalArgumentException { + Class contextClass = context.getClass(); + + if (FindsByAndroidUIAutomator.class.isAssignableFrom(contextClass)) { + return FindsByAndroidUIAutomator.class.cast(context) .findElementsByAndroidUIAutomator(getLocatorString()); + } + + if (FindsByFluentSelector.class.isAssignableFrom(context.getClass())) { + return super.findElements(context); + } + + throw formIllegalArgumentException(contextClass, FindsByAndroidUIAutomator.class, + FindsByFluentSelector.class); } - @Override public WebElement findElement(SearchContext context) { - return ((FindsByAndroidUIAutomator) context) - .findElementByAndroidUIAutomator(getLocatorString()); + /** + * @throws WebDriverException when current session doesn't support the given selector or when + * value of the selector is not consistent. + * @throws IllegalArgumentException when it is impossible to find something on the given + * {@link SearchContext} instance + */ + @Override public WebElement findElement(SearchContext context) throws WebDriverException, + IllegalArgumentException { + Class contextClass = context.getClass(); + + if (FindsByAndroidUIAutomator.class.isAssignableFrom(contextClass)) { + return FindsByAndroidUIAutomator.class.cast(context) + .findElementByAndroidUIAutomator(getLocatorString()); + } + + if (FindsByFluentSelector.class.isAssignableFrom(context.getClass())) { + return super.findElement(context); + } + + throw formIllegalArgumentException(contextClass, FindsByAndroidUIAutomator.class, + FindsByFluentSelector.class); } @Override public String toString() { @@ -126,19 +221,55 @@ public List findElements(SearchContext context) { public static class ByAccessibilityId extends MobileBy implements Serializable { public ByAccessibilityId(String accessibilityId) { - super(accessibilityId); + super(MobileSelector.ACCESSIBILITY, accessibilityId); } + /** + * @throws WebDriverException when current session doesn't support the given selector or when + * value of the selector is not consistent. + * @throws IllegalArgumentException when it is impossible to find something on the given + * {@link SearchContext} instance + */ @SuppressWarnings("unchecked") @Override - public List findElements(SearchContext context) { - return (List) ((FindsByAccessibilityId) context) - .findElementsByAccessibilityId(getLocatorString()); + public List findElements(SearchContext context) throws WebDriverException, + IllegalArgumentException { + Class contextClass = context.getClass(); + + if (FindsByAccessibilityId.class.isAssignableFrom(contextClass)) { + return FindsByAccessibilityId.class.cast(context) + .findElementsByAccessibilityId(getLocatorString()); + } + + if (FindsByFluentSelector.class.isAssignableFrom(context.getClass())) { + return super.findElements(context); + } + + throw formIllegalArgumentException(contextClass, FindsByAccessibilityId.class, + FindsByFluentSelector.class); } - @Override public WebElement findElement(SearchContext context) { - return ((FindsByAccessibilityId) context) + /** + * @throws WebDriverException when current session doesn't support the given selector or when + * value of the selector is not consistent. + * @throws IllegalArgumentException when it is impossible to find something on the given + * {@link SearchContext} instance + */ + @Override public WebElement findElement(SearchContext context) throws WebDriverException, + IllegalArgumentException { + Class contextClass = context.getClass(); + + if (FindsByAccessibilityId.class.isAssignableFrom(contextClass)) { + return FindsByAccessibilityId.class.cast(context) .findElementByAccessibilityId(getLocatorString()); + } + + if (FindsByFluentSelector.class.isAssignableFrom(context.getClass())) { + return super.findElement(context); + } + + throw formIllegalArgumentException(contextClass, FindsByAccessibilityId.class, + FindsByFluentSelector.class); } @Override public String toString() { diff --git a/src/main/java/io/appium/java_client/MobileDriver.java b/src/main/java/io/appium/java_client/MobileDriver.java index e6965aef9..c53ccecca 100644 --- a/src/main/java/io/appium/java_client/MobileDriver.java +++ b/src/main/java/io/appium/java_client/MobileDriver.java @@ -37,7 +37,7 @@ public interface MobileDriver extends WebDriver, PerformsTouchActions, ContextAware, Rotatable, FindsByAccessibilityId, LocationContext, DeviceActionShortcuts, TouchShortcuts, InteractsWithFiles, InteractsWithApps, HasAppStrings, FindsByClassName, FindsByCssSelector, FindsById, - FindsByLinkText, FindsByName, FindsByTagName, FindsByXPath { + FindsByLinkText, FindsByName, FindsByTagName, FindsByXPath, FindsByFluentSelector { Response execute(String driverCommand, Map parameters); diff --git a/src/main/java/io/appium/java_client/MobileSelector.java b/src/main/java/io/appium/java_client/MobileSelector.java new file mode 100644 index 000000000..532113b51 --- /dev/null +++ b/src/main/java/io/appium/java_client/MobileSelector.java @@ -0,0 +1,33 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.appium.java_client; + +public enum MobileSelector { + ACCESSIBILITY("accessibility id"), + ANDROID_UI_AUTOMATOR("-android uiautomator"), + IOS_UI_AUTOMATION("-ios uiautomation"); + + private final String selector; + + MobileSelector(String selector) { + this.selector = selector; + } + + @Override public String toString() { + return selector; + } +} diff --git a/src/main/java/io/appium/java_client/TouchableElement.java b/src/main/java/io/appium/java_client/TouchableElement.java index 757c99626..5773dcc43 100644 --- a/src/main/java/io/appium/java_client/TouchableElement.java +++ b/src/main/java/io/appium/java_client/TouchableElement.java @@ -34,7 +34,7 @@ */ public interface TouchableElement extends WebElement, FindsByClassName, FindsByCssSelector, FindsById, - FindsByLinkText, FindsByName, FindsByTagName, FindsByXPath { + FindsByLinkText, FindsByName, FindsByTagName, FindsByXPath, FindsByFluentSelector { List findElements(By by); diff --git a/src/main/java/io/appium/java_client/android/AndroidDriver.java b/src/main/java/io/appium/java_client/android/AndroidDriver.java index 2ba445996..91d082f94 100644 --- a/src/main/java/io/appium/java_client/android/AndroidDriver.java +++ b/src/main/java/io/appium/java_client/android/AndroidDriver.java @@ -36,6 +36,7 @@ import io.appium.java_client.AppiumSetting; import io.appium.java_client.CommandExecutionHelper; import io.appium.java_client.FindsByAndroidUIAutomator; +import io.appium.java_client.MobileSelector; import io.appium.java_client.android.internal.JsonToAndroidElementConverter; import io.appium.java_client.remote.MobilePlatform; import io.appium.java_client.service.local.AppiumDriverLocalService; @@ -362,7 +363,7 @@ public void ignoreUnimportantViews(Boolean compress) { @Override public T findElementByAndroidUIAutomator(String using) throws WebDriverException { - return findElement("-android uiautomator", using); + return findElement(MobileSelector.ANDROID_UI_AUTOMATOR.toString(), using); } /** @@ -372,7 +373,7 @@ public T findElementByAndroidUIAutomator(String using) @Override public List findElementsByAndroidUIAutomator(String using) throws WebDriverException { - return findElements("-android uiautomator", using); + return findElements(MobileSelector.ANDROID_UI_AUTOMATOR.toString(), using); } /** diff --git a/src/main/java/io/appium/java_client/android/AndroidElement.java b/src/main/java/io/appium/java_client/android/AndroidElement.java index 82bab2088..8dd9b2825 100644 --- a/src/main/java/io/appium/java_client/android/AndroidElement.java +++ b/src/main/java/io/appium/java_client/android/AndroidElement.java @@ -21,6 +21,7 @@ import io.appium.java_client.CommandExecutionHelper; import io.appium.java_client.FindsByAndroidUIAutomator; import io.appium.java_client.MobileElement; +import io.appium.java_client.MobileSelector; import org.openqa.selenium.WebDriverException; @@ -35,7 +36,7 @@ public class AndroidElement extends MobileElement */ @Override public MobileElement findElementByAndroidUIAutomator(String using) throws WebDriverException { - return findElement("-android uiautomator", using); + return findElement(MobileSelector.ANDROID_UI_AUTOMATOR.toString(), using); } /** @@ -43,7 +44,7 @@ public class AndroidElement extends MobileElement */ @Override public List findElementsByAndroidUIAutomator(String using) throws WebDriverException { - return findElements("-android uiautomator", using); + return findElements(MobileSelector.ANDROID_UI_AUTOMATOR.toString(), using); } /** diff --git a/src/main/java/io/appium/java_client/ios/IOSDriver.java b/src/main/java/io/appium/java_client/ios/IOSDriver.java index 11ebb9512..24d633d45 100644 --- a/src/main/java/io/appium/java_client/ios/IOSDriver.java +++ b/src/main/java/io/appium/java_client/ios/IOSDriver.java @@ -24,6 +24,7 @@ import io.appium.java_client.AppiumDriver; import io.appium.java_client.CommandExecutionHelper; import io.appium.java_client.FindsByIosUIAutomation; +import io.appium.java_client.MobileSelector; import io.appium.java_client.ios.internal.JsonToIOSElementConverter; import io.appium.java_client.remote.MobilePlatform; import io.appium.java_client.service.local.AppiumDriverLocalService; @@ -204,7 +205,7 @@ public IOSDriver(Capabilities desiredCapabilities) { @Override public T findElementByIosUIAutomation(String using) throws WebDriverException { - return findElement("-ios uiautomation", using); + return findElement(MobileSelector.IOS_UI_AUTOMATION.toString(), using); } /** @@ -213,7 +214,7 @@ public T findElementByIosUIAutomation(String using) @Override public List findElementsByIosUIAutomation(String using) throws WebDriverException { - return findElements("-ios uiautomation", using); + return findElements(MobileSelector.IOS_UI_AUTOMATION.toString(), using); } /** diff --git a/src/main/java/io/appium/java_client/ios/IOSElement.java b/src/main/java/io/appium/java_client/ios/IOSElement.java index 723989b09..86cd3ab0b 100644 --- a/src/main/java/io/appium/java_client/ios/IOSElement.java +++ b/src/main/java/io/appium/java_client/ios/IOSElement.java @@ -18,6 +18,7 @@ import io.appium.java_client.FindsByIosUIAutomation; import io.appium.java_client.MobileElement; +import io.appium.java_client.MobileSelector; import org.openqa.selenium.WebDriverException; import java.util.List; @@ -30,7 +31,7 @@ public class IOSElement extends MobileElement */ @Override public MobileElement findElementByIosUIAutomation(String using) throws WebDriverException { - return findElement("-ios uiautomation", using); + return findElement(MobileSelector.IOS_UI_AUTOMATION.toString(), using); } /** @@ -39,6 +40,6 @@ public class IOSElement extends MobileElement */ @Override public List findElementsByIosUIAutomation(String using) throws WebDriverException { - return findElements("-ios uiautomation", using); + return findElements(MobileSelector.IOS_UI_AUTOMATION.toString(), using); } } From 94063b7bbe25f44dbdb7310c50ce929bbb6f6efd Mon Sep 17 00:00:00 2001 From: Date: Tue, 23 Aug 2016 22:35:31 +0300 Subject: [PATCH 2/4] The searching by IosNSPredicate.java --- .../java_client/FindsByIosNSPredicate.java | 28 ++++++++ .../java/io/appium/java_client/MobileBy.java | 65 +++++++++++++++++++ .../io/appium/java_client/MobileSelector.java | 3 +- 3 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 src/main/java/io/appium/java_client/FindsByIosNSPredicate.java diff --git a/src/main/java/io/appium/java_client/FindsByIosNSPredicate.java b/src/main/java/io/appium/java_client/FindsByIosNSPredicate.java new file mode 100644 index 000000000..59c5f18d0 --- /dev/null +++ b/src/main/java/io/appium/java_client/FindsByIosNSPredicate.java @@ -0,0 +1,28 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.appium.java_client; + +import org.openqa.selenium.WebElement; + +import java.util.List; + +public interface FindsByIosNSPredicate { + + T findElementByIosNsPredicate(String using); + + List findElementsByIosNsPredicate(String using); +} diff --git a/src/main/java/io/appium/java_client/MobileBy.java b/src/main/java/io/appium/java_client/MobileBy.java index 5c9ad4975..2d614330d 100644 --- a/src/main/java/io/appium/java_client/MobileBy.java +++ b/src/main/java/io/appium/java_client/MobileBy.java @@ -96,6 +96,15 @@ public static By AndroidUIAutomator(final String uiautomatorText) { public static By AccessibilityId(final String accessibilityId) { return new ByAccessibilityId(accessibilityId); } + + /** + * This locator strategy is available in XCUITest Driver mode + * @param iOSNsPredicateString is an an iOS NsPredicate String + * @return an instance of {@link io.appium.java_client.MobileBy.ByIosNsPredicate} + */ + public static By IosNsPredicateString(final String iOSNsPredicateString) { + return new ByIosNsPredicate(iOSNsPredicateString); + } public static class ByIosUIAutomation extends MobileBy implements Serializable { @@ -276,6 +285,62 @@ public List findElements(SearchContext context) throws WebDriverExce return "By.AccessibilityId: " + getLocatorString(); } } + + public static class ByIosNsPredicate extends MobileBy implements Serializable { + + protected ByIosNsPredicate(String locatorString) { + super(MobileSelector.IOS_PREDICATE_STRING, locatorString); + } + + /** + * @throws WebDriverException when current session doesn't support the given selector or when + * value of the selector is not consistent. + * @throws IllegalArgumentException when it is impossible to find something on the given + * {@link SearchContext} instance + */ + @SuppressWarnings("unchecked") + @Override public List findElements(SearchContext context) { + Class contextClass = context.getClass(); + + if (FindsByIosNSPredicate.class.isAssignableFrom(contextClass)) { + return FindsByIosNSPredicate.class.cast(context) + .findElementsByIosNsPredicate(getLocatorString()); + } + + if (FindsByFluentSelector.class.isAssignableFrom(context.getClass())) { + return super.findElements(context); + } + + throw formIllegalArgumentException(contextClass, FindsByIosNSPredicate.class, + FindsByFluentSelector.class); + } + + /** + * @throws WebDriverException when current session doesn't support the given selector or when + * value of the selector is not consistent. + * @throws IllegalArgumentException when it is impossible to find something on the given + * {@link SearchContext} instance + */ + @Override public WebElement findElement(SearchContext context) { + Class contextClass = context.getClass(); + + if (FindsByIosNSPredicate.class.isAssignableFrom(contextClass)) { + return FindsByIosNSPredicate.class.cast(context) + .findElementByIosNsPredicate(getLocatorString()); + } + + if (FindsByFluentSelector.class.isAssignableFrom(context.getClass())) { + return super.findElement(context); + } + + throw formIllegalArgumentException(contextClass, FindsByIosNSPredicate.class, + FindsByFluentSelector.class); + } + + @Override public String toString() { + return "By.IosNsPredicate: " + getLocatorString(); + } + } } diff --git a/src/main/java/io/appium/java_client/MobileSelector.java b/src/main/java/io/appium/java_client/MobileSelector.java index 532113b51..34a3a9f10 100644 --- a/src/main/java/io/appium/java_client/MobileSelector.java +++ b/src/main/java/io/appium/java_client/MobileSelector.java @@ -19,7 +19,8 @@ public enum MobileSelector { ACCESSIBILITY("accessibility id"), ANDROID_UI_AUTOMATOR("-android uiautomator"), - IOS_UI_AUTOMATION("-ios uiautomation"); + IOS_UI_AUTOMATION("-ios uiautomation"), + IOS_PREDICATE_STRING("-ios predicate string"); private final String selector; From dbd958a7a46d01eb964a677ae6d628bd01945aa6 Mon Sep 17 00:00:00 2001 From: jonstoneman Date: Thu, 25 Aug 2016 19:15:57 +0300 Subject: [PATCH 3/4] #455 fix. The searching by Windows automation --- .../java_client/FindsByWindowsAutomation.java | 41 +++++++++++++++ .../java/io/appium/java_client/MobileBy.java | 52 +++++++++++++++++++ .../io/appium/java_client/MobileSelector.java | 3 +- 3 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 src/main/java/io/appium/java_client/FindsByWindowsAutomation.java diff --git a/src/main/java/io/appium/java_client/FindsByWindowsAutomation.java b/src/main/java/io/appium/java_client/FindsByWindowsAutomation.java new file mode 100644 index 000000000..84d77ca86 --- /dev/null +++ b/src/main/java/io/appium/java_client/FindsByWindowsAutomation.java @@ -0,0 +1,41 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package io.appium.java_client; + +import org.openqa.selenium.WebElement; + +import java.util.List; + +public interface FindsByWindowsAutomation { + + /** + * Finds the first of elements that match the Windows UIAutomation selector supplied. + * + * @param selector a Windows UIAutomation selector + * @return The first element that matches the given selector + */ + T findElementByWindowsUIAutomation(String selector); + + /** + * Finds a list of elements that match the Windows UIAutomation selector supplied. + * + * @param selector a Windows UIAutomation selector + * @return a list of elements that match the given selector + */ + List findElementsByWindowsUIAutomation(String selector); +} diff --git a/src/main/java/io/appium/java_client/MobileBy.java b/src/main/java/io/appium/java_client/MobileBy.java index 2d614330d..9f1f3d2a8 100644 --- a/src/main/java/io/appium/java_client/MobileBy.java +++ b/src/main/java/io/appium/java_client/MobileBy.java @@ -341,6 +341,58 @@ protected ByIosNsPredicate(String locatorString) { return "By.IosNsPredicate: " + getLocatorString(); } } + + public static class ByWindowsAutomation extends MobileBy implements Serializable { + + protected ByWindowsAutomation(String locatorString) { + super(MobileSelector.WINDOWS_UI_AUTOMATION, locatorString); + } + + /** + * @throws WebDriverException when current session doesn't support the given selector or when + * value of the selector is not consistent. + * @throws IllegalArgumentException when it is impossible to find something on the given + * {@link SearchContext} instance + */ + @SuppressWarnings("unchecked") + @Override public List findElements(SearchContext context) { + Class contextClass = context.getClass(); + + if (FindsByWindowsAutomation.class.isAssignableFrom(contextClass)) { + return FindsByWindowsAutomation.class.cast(context) + .findElementsByWindowsUIAutomation(getLocatorString()); + } + + if (FindsByFluentSelector.class.isAssignableFrom(context.getClass())) { + return super.findElements(context); + } + + throw formIllegalArgumentException(contextClass, FindsByWindowsAutomation.class, + FindsByFluentSelector.class); + } + + /** + * @throws WebDriverException when current session doesn't support the given selector or when + * value of the selector is not consistent. + * @throws IllegalArgumentException when it is impossible to find something on the given + * {@link SearchContext} instance + */ + @Override public WebElement findElement(SearchContext context) { + Class contextClass = context.getClass(); + + if (FindsByWindowsAutomation.class.isAssignableFrom(contextClass)) { + return FindsByWindowsAutomation.class.cast(context) + .findElementByWindowsUIAutomation(getLocatorString()); + } + + if (FindsByFluentSelector.class.isAssignableFrom(context.getClass())) { + return super.findElement(context); + } + + throw formIllegalArgumentException(contextClass, FindsByIosNSPredicate.class, + FindsByWindowsAutomation.class); + } + } } diff --git a/src/main/java/io/appium/java_client/MobileSelector.java b/src/main/java/io/appium/java_client/MobileSelector.java index 34a3a9f10..f70c64fc1 100644 --- a/src/main/java/io/appium/java_client/MobileSelector.java +++ b/src/main/java/io/appium/java_client/MobileSelector.java @@ -20,7 +20,8 @@ public enum MobileSelector { ACCESSIBILITY("accessibility id"), ANDROID_UI_AUTOMATOR("-android uiautomator"), IOS_UI_AUTOMATION("-ios uiautomation"), - IOS_PREDICATE_STRING("-ios predicate string"); + IOS_PREDICATE_STRING("-ios predicate string"), + WINDOWS_UI_AUTOMATION("-windows uiautomation"); private final String selector; From 2a83d6da01156263922be0c206fe717bfe8cbff2 Mon Sep 17 00:00:00 2001 From: TikhomirovSergey Date: Fri, 26 Aug 2016 12:14:24 +0300 Subject: [PATCH 4/4] #455 fix. Issues that found by Codecy were fixed --- src/main/java/io/appium/java_client/MobileBy.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/io/appium/java_client/MobileBy.java b/src/main/java/io/appium/java_client/MobileBy.java index 9f1f3d2a8..f9917ef01 100644 --- a/src/main/java/io/appium/java_client/MobileBy.java +++ b/src/main/java/io/appium/java_client/MobileBy.java @@ -102,9 +102,13 @@ public static By AccessibilityId(final String accessibilityId) { * @param iOSNsPredicateString is an an iOS NsPredicate String * @return an instance of {@link io.appium.java_client.MobileBy.ByIosNsPredicate} */ - public static By IosNsPredicateString(final String iOSNsPredicateString) { + public static By iOSNsPredicateString(final String iOSNsPredicateString) { return new ByIosNsPredicate(iOSNsPredicateString); } + + public static By windowsAutomation(final String windowsAutomation) { + return new ByWindowsAutomation(windowsAutomation); + } public static class ByIosUIAutomation extends MobileBy implements Serializable {