From f4cdaf7821d368e9eefbdffefdc9d7fd03a7ae65 Mon Sep 17 00:00:00 2001 From: Srinivasan Sekar Date: Mon, 19 Aug 2019 23:39:39 +0530 Subject: [PATCH 001/690] Fix #1208 (#1209) This reverts commit 6d0de818812878009e15fc055136933b14030020. --- gradle.properties | 2 +- .../io/appium/java_client/remote/AppiumCommandExecutor.java | 2 +- .../io/appium/java_client/remote/AppiumW3CHttpCommandCodec.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gradle.properties b/gradle.properties index 5a9863788..9bd535700 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,4 +7,4 @@ signing.secretKeyRingFile=PathToYourKeyRingFile ossrhUsername=your-jira-id ossrhPassword=your-jira-password -selenium.version=4.0.0-alpha-1 +selenium.version=3.141.59 diff --git a/src/main/java/io/appium/java_client/remote/AppiumCommandExecutor.java b/src/main/java/io/appium/java_client/remote/AppiumCommandExecutor.java index 707680b4f..3f094ff53 100644 --- a/src/main/java/io/appium/java_client/remote/AppiumCommandExecutor.java +++ b/src/main/java/io/appium/java_client/remote/AppiumCommandExecutor.java @@ -44,10 +44,10 @@ import org.openqa.selenium.remote.ProtocolHandshake; import org.openqa.selenium.remote.Response; import org.openqa.selenium.remote.ResponseCodec; -import org.openqa.selenium.remote.codec.w3c.W3CHttpCommandCodec; import org.openqa.selenium.remote.http.HttpClient; import org.openqa.selenium.remote.http.HttpRequest; import org.openqa.selenium.remote.http.HttpResponse; +import org.openqa.selenium.remote.http.W3CHttpCommandCodec; import org.openqa.selenium.remote.service.DriverService; import java.io.BufferedInputStream; diff --git a/src/main/java/io/appium/java_client/remote/AppiumW3CHttpCommandCodec.java b/src/main/java/io/appium/java_client/remote/AppiumW3CHttpCommandCodec.java index 0fe0ace05..aec7ebd75 100644 --- a/src/main/java/io/appium/java_client/remote/AppiumW3CHttpCommandCodec.java +++ b/src/main/java/io/appium/java_client/remote/AppiumW3CHttpCommandCodec.java @@ -32,7 +32,7 @@ import org.openqa.selenium.interactions.KeyInput; import org.openqa.selenium.interactions.Sequence; -import org.openqa.selenium.remote.codec.w3c.W3CHttpCommandCodec; +import org.openqa.selenium.remote.http.W3CHttpCommandCodec; import java.util.Collection; import java.util.Map; From 7239a9d44cd088b6c457c93ac8a90a4cf797dd17 Mon Sep 17 00:00:00 2001 From: Wasiq Bhamla Date: Wed, 21 Aug 2019 01:51:26 +0530 Subject: [PATCH 002/690] Upgraded Selenium version to alpha 2. (#1210) * Upgraded Selenium version to alpha 2. * Updated for changes for Selenium alpha 2. * Updated for compilation errors. --- gradle.properties | 2 +- .../appium/java_client/remote/AppiumCommandExecutor.java | 2 +- .../java_client/remote/AppiumW3CHttpCommandCodec.java | 2 +- .../java_client/android/OpenNotificationsTest.java | 3 ++- .../io/appium/java_client/android/UIAutomator2Test.java | 9 +++++---- .../element/generation/ios/IOSElementGenerationTest.java | 5 +++-- .../java/io/appium/java_client/ios/IOSAlertTest.java | 3 ++- .../java/io/appium/java_client/ios/IOSDriverTest.java | 9 +++++---- .../java/io/appium/java_client/ios/IOSElementTest.java | 3 ++- .../java_client/ios/IOSNativeWebTapSettingTest.java | 7 ++++--- .../java/io/appium/java_client/ios/IOSTouchTest.java | 4 ++-- .../java/io/appium/java_client/ios/IOSWebViewTest.java | 7 +++++-- .../java_client/pagefactory_tests/XCUITModeTest.java | 3 ++- 13 files changed, 35 insertions(+), 24 deletions(-) diff --git a/gradle.properties b/gradle.properties index 9bd535700..63b13d41e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,4 +7,4 @@ signing.secretKeyRingFile=PathToYourKeyRingFile ossrhUsername=your-jira-id ossrhPassword=your-jira-password -selenium.version=3.141.59 +selenium.version=4.0.0-alpha-2 \ No newline at end of file diff --git a/src/main/java/io/appium/java_client/remote/AppiumCommandExecutor.java b/src/main/java/io/appium/java_client/remote/AppiumCommandExecutor.java index 3f094ff53..707680b4f 100644 --- a/src/main/java/io/appium/java_client/remote/AppiumCommandExecutor.java +++ b/src/main/java/io/appium/java_client/remote/AppiumCommandExecutor.java @@ -44,10 +44,10 @@ import org.openqa.selenium.remote.ProtocolHandshake; import org.openqa.selenium.remote.Response; import org.openqa.selenium.remote.ResponseCodec; +import org.openqa.selenium.remote.codec.w3c.W3CHttpCommandCodec; import org.openqa.selenium.remote.http.HttpClient; import org.openqa.selenium.remote.http.HttpRequest; import org.openqa.selenium.remote.http.HttpResponse; -import org.openqa.selenium.remote.http.W3CHttpCommandCodec; import org.openqa.selenium.remote.service.DriverService; import java.io.BufferedInputStream; diff --git a/src/main/java/io/appium/java_client/remote/AppiumW3CHttpCommandCodec.java b/src/main/java/io/appium/java_client/remote/AppiumW3CHttpCommandCodec.java index aec7ebd75..0fe0ace05 100644 --- a/src/main/java/io/appium/java_client/remote/AppiumW3CHttpCommandCodec.java +++ b/src/main/java/io/appium/java_client/remote/AppiumW3CHttpCommandCodec.java @@ -32,7 +32,7 @@ import org.openqa.selenium.interactions.KeyInput; import org.openqa.selenium.interactions.Sequence; -import org.openqa.selenium.remote.http.W3CHttpCommandCodec; +import org.openqa.selenium.remote.codec.w3c.W3CHttpCommandCodec; import java.util.Collection; import java.util.Map; diff --git a/src/test/java/io/appium/java_client/android/OpenNotificationsTest.java b/src/test/java/io/appium/java_client/android/OpenNotificationsTest.java index 7806ecc14..d6af69d05 100644 --- a/src/test/java/io/appium/java_client/android/OpenNotificationsTest.java +++ b/src/test/java/io/appium/java_client/android/OpenNotificationsTest.java @@ -1,5 +1,6 @@ package io.appium.java_client.android; +import static java.time.Duration.ofSeconds; import static org.junit.Assert.assertNotEquals; import static org.openqa.selenium.By.id; @@ -14,7 +15,7 @@ public class OpenNotificationsTest extends BaseAndroidTest { public void openNotification() { driver.closeApp(); driver.openNotifications(); - WebDriverWait wait = new WebDriverWait(driver, 20); + WebDriverWait wait = new WebDriverWait(driver, ofSeconds(20)); assertNotEquals(0, wait.until(input -> { List result = input .findElements(id("com.android.systemui:id/settings_button")); diff --git a/src/test/java/io/appium/java_client/android/UIAutomator2Test.java b/src/test/java/io/appium/java_client/android/UIAutomator2Test.java index 19df3618a..bca878dda 100644 --- a/src/test/java/io/appium/java_client/android/UIAutomator2Test.java +++ b/src/test/java/io/appium/java_client/android/UIAutomator2Test.java @@ -1,5 +1,6 @@ package io.appium.java_client.android; +import static java.time.Duration.ofSeconds; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -23,7 +24,7 @@ public void afterMethod() { @Test public void testLandscapeRightRotation() { - new WebDriverWait(driver, 20).until(ExpectedConditions + new WebDriverWait(driver, ofSeconds(20)).until(ExpectedConditions .elementToBeClickable(driver.findElementById("android:id/content") .findElement(MobileBy.AccessibilityId("Graphics")))); DeviceRotation landscapeRightRotation = new DeviceRotation(0, 0, 90); @@ -33,7 +34,7 @@ public void testLandscapeRightRotation() { @Test public void testLandscapeLeftRotation() { - new WebDriverWait(driver, 20).until(ExpectedConditions + new WebDriverWait(driver, ofSeconds(20)).until(ExpectedConditions .elementToBeClickable(driver.findElementById("android:id/content") .findElement(MobileBy.AccessibilityId("Graphics")))); DeviceRotation landscapeLeftRotation = new DeviceRotation(0, 0, 270); @@ -43,7 +44,7 @@ public void testLandscapeLeftRotation() { @Test public void testPortraitUpsideDown() { - new WebDriverWait(driver, 20).until(ExpectedConditions + new WebDriverWait(driver, ofSeconds(20)).until(ExpectedConditions .elementToBeClickable(driver.findElementById("android:id/content") .findElement(MobileBy.AccessibilityId("Graphics")))); DeviceRotation landscapeRightRotation = new DeviceRotation(0, 0, 180); @@ -56,7 +57,7 @@ public void testPortraitUpsideDown() { */ @Ignore public void testToastMSGIsDisplayed() { - final WebDriverWait wait = new WebDriverWait(driver, 30); + final WebDriverWait wait = new WebDriverWait(driver, ofSeconds(30)); Activity activity = new Activity("io.appium.android.apis", ".view.PopupMenu1"); driver.startActivity(activity); diff --git a/src/test/java/io/appium/java_client/appium/element/generation/ios/IOSElementGenerationTest.java b/src/test/java/io/appium/java_client/appium/element/generation/ios/IOSElementGenerationTest.java index 0b7572be3..7ed8832e5 100644 --- a/src/test/java/io/appium/java_client/appium/element/generation/ios/IOSElementGenerationTest.java +++ b/src/test/java/io/appium/java_client/appium/element/generation/ios/IOSElementGenerationTest.java @@ -1,6 +1,7 @@ package io.appium.java_client.appium.element.generation.ios; import static io.appium.java_client.MobileBy.AccessibilityId; +import static java.time.Duration.ofSeconds; import static org.junit.Assert.assertTrue; import static org.openqa.selenium.By.id; import static org.openqa.selenium.By.name; @@ -84,11 +85,11 @@ public void whenIOSHybridAppIsLaunched() { Capabilities caps = commonAppCapabilitiesSupplier.get(); return caps.merge(appFileSupplierFunction.apply(webViewApp).get()); }, (by, aClass) -> { - new WebDriverWait(driver, 30) + new WebDriverWait(driver, ofSeconds(30)) .until(ExpectedConditions.presenceOfElementLocated(id("login"))) .click(); driver.findElementByAccessibilityId("webView").click(); - new WebDriverWait(driver, 30) + new WebDriverWait(driver, ofSeconds(30)) .until(ExpectedConditions .presenceOfElementLocated(AccessibilityId("Webview"))); try { diff --git a/src/test/java/io/appium/java_client/ios/IOSAlertTest.java b/src/test/java/io/appium/java_client/ios/IOSAlertTest.java index 06df51bd7..7c46a3c4d 100644 --- a/src/test/java/io/appium/java_client/ios/IOSAlertTest.java +++ b/src/test/java/io/appium/java_client/ios/IOSAlertTest.java @@ -16,6 +16,7 @@ package io.appium.java_client.ios; +import static java.time.Duration.ofSeconds; import static junit.framework.TestCase.assertFalse; import static org.junit.Assert.assertTrue; import static org.openqa.selenium.support.ui.ExpectedConditions.alertIsPresent; @@ -32,7 +33,7 @@ @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class IOSAlertTest extends AppIOSTest { - private WebDriverWait waiting = new WebDriverWait(driver, 10000); + private WebDriverWait waiting = new WebDriverWait(driver, ofSeconds(10000)); private static final String iOSAutomationText = "show alert"; @Test public void acceptAlertTest() { diff --git a/src/test/java/io/appium/java_client/ios/IOSDriverTest.java b/src/test/java/io/appium/java_client/ios/IOSDriverTest.java index 995ac4c58..69056af48 100644 --- a/src/test/java/io/appium/java_client/ios/IOSDriverTest.java +++ b/src/test/java/io/appium/java_client/ios/IOSDriverTest.java @@ -16,6 +16,7 @@ package io.appium.java_client.ios; +import static java.time.Duration.ofSeconds; import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.greaterThan; @@ -56,7 +57,7 @@ public void getDeviceTimeTest() { } @Test public void hideKeyboardWithParametersTest() { - new WebDriverWait(driver, 30) + new WebDriverWait(driver, ofSeconds(30)) .until(ExpectedConditions.presenceOfElementLocated(By.id("IntegerA"))) .click(); driver.hideKeyboard(HideKeyboardStrategy.PRESS_KEY, "Done"); @@ -102,7 +103,7 @@ public void getDeviceTimeTest() { @Test public void putAppIntoBackgroundAndRestoreTest() { final long msStarted = System.currentTimeMillis(); - driver.runAppInBackground(Duration.ofSeconds(4)); + driver.runAppInBackground(ofSeconds(4)); assertThat(System.currentTimeMillis() - msStarted, greaterThan(3000L)); } @@ -119,7 +120,7 @@ public void getDeviceTimeTest() { } assertThat(driver.queryAppState(BUNDLE_ID), equalTo(ApplicationState.RUNNING_IN_FOREGROUND)); Thread.sleep(500); - driver.runAppInBackground(Duration.ofSeconds(-1)); + driver.runAppInBackground(ofSeconds(-1)); assertThat(driver.queryAppState(BUNDLE_ID), lessThan(ApplicationState.RUNNING_IN_FOREGROUND)); Thread.sleep(500); driver.activateApp(BUNDLE_ID); @@ -128,7 +129,7 @@ public void getDeviceTimeTest() { @Test public void putAIntoBackgroundWithoutRestoreTest() { assertThat(driver.findElementsById("IntegerA"), is(not(empty()))); - driver.runAppInBackground(Duration.ofSeconds(-1)); + driver.runAppInBackground(ofSeconds(-1)); assertThat(driver.findElementsById("IntegerA"), is(empty())); driver.launchApp(); } diff --git a/src/test/java/io/appium/java_client/ios/IOSElementTest.java b/src/test/java/io/appium/java_client/ios/IOSElementTest.java index 4389d1888..18bbf0d69 100644 --- a/src/test/java/io/appium/java_client/ios/IOSElementTest.java +++ b/src/test/java/io/appium/java_client/ios/IOSElementTest.java @@ -1,5 +1,6 @@ package io.appium.java_client.ios; +import static java.time.Duration.ofSeconds; import static org.hamcrest.core.Is.is; import static org.hamcrest.core.IsNot.not; import static org.junit.Assert.assertEquals; @@ -25,7 +26,7 @@ public void findByAccessibilityIdTest() { @Ignore @Test public void setValueTest() { - WebDriverWait wait = new WebDriverWait(driver, 20); + WebDriverWait wait = new WebDriverWait(driver, ofSeconds(20)); IOSElement slider = wait.until( driver1 -> driver1.findElement(By.className("XCUIElementTypeSlider"))); diff --git a/src/test/java/io/appium/java_client/ios/IOSNativeWebTapSettingTest.java b/src/test/java/io/appium/java_client/ios/IOSNativeWebTapSettingTest.java index cc23af210..25f287bc5 100644 --- a/src/test/java/io/appium/java_client/ios/IOSNativeWebTapSettingTest.java +++ b/src/test/java/io/appium/java_client/ios/IOSNativeWebTapSettingTest.java @@ -1,5 +1,6 @@ package io.appium.java_client.ios; +import static java.time.Duration.ofSeconds; import static org.junit.Assert.assertTrue; import org.junit.Test; @@ -16,17 +17,17 @@ public class IOSNativeWebTapSettingTest extends BaseSafariTest { driver.nativeWebTap(true); WebElement el = driver.findElementById("i am a link"); el.click(); - assertTrue(new WebDriverWait(driver, 30) + assertTrue(new WebDriverWait(driver, ofSeconds(30)) .until(ExpectedConditions.titleIs("I am another page title - Sauce Labs"))); driver.navigate().back(); // now do a click with it turned off and assert the same behavior - assertTrue(new WebDriverWait(driver, 30) + assertTrue(new WebDriverWait(driver, ofSeconds(30)) .until(ExpectedConditions.titleIs("I am a page title - Sauce Labs"))); driver.nativeWebTap(false); el = driver.findElementById("i am a link"); el.click(); - assertTrue(new WebDriverWait(driver, 30) + assertTrue(new WebDriverWait(driver, ofSeconds(30)) .until(ExpectedConditions.titleIs("I am another page title - Sauce Labs"))); } } diff --git a/src/test/java/io/appium/java_client/ios/IOSTouchTest.java b/src/test/java/io/appium/java_client/ios/IOSTouchTest.java index ea2f83d9d..8b6d34b04 100644 --- a/src/test/java/io/appium/java_client/ios/IOSTouchTest.java +++ b/src/test/java/io/appium/java_client/ios/IOSTouchTest.java @@ -58,7 +58,7 @@ public void touchWithPressureTest() { } @Test public void swipeTest() { - WebDriverWait webDriverWait = new WebDriverWait(driver, 30); + WebDriverWait webDriverWait = new WebDriverWait(driver, ofSeconds(30)); IOSElement slider = webDriverWait.until(driver1 -> driver.findElementByClassName("XCUIElementTypeSlider")); Dimension size = slider.getSize(); @@ -82,7 +82,7 @@ public void touchWithPressureTest() { new MultiTouchAction(driver).add(tap1).add(tap2).perform(); - WebDriverWait waiting = new WebDriverWait(driver, 10000); + WebDriverWait waiting = new WebDriverWait(driver, ofSeconds(10000)); assertNotNull(waiting.until(alertIsPresent())); driver.switchTo().alert().accept(); } diff --git a/src/test/java/io/appium/java_client/ios/IOSWebViewTest.java b/src/test/java/io/appium/java_client/ios/IOSWebViewTest.java index 7c8f380c3..d12d5aa16 100644 --- a/src/test/java/io/appium/java_client/ios/IOSWebViewTest.java +++ b/src/test/java/io/appium/java_client/ios/IOSWebViewTest.java @@ -1,5 +1,6 @@ package io.appium.java_client.ios; +import static java.time.Duration.ofSeconds; import static org.junit.Assert.assertTrue; import io.appium.java_client.MobileBy; @@ -9,14 +10,16 @@ import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; +import java.time.Duration; + public class IOSWebViewTest extends BaseIOSWebViewTest { @Test public void webViewPageTestCase() throws InterruptedException { - new WebDriverWait(driver, 30) + new WebDriverWait(driver, ofSeconds(30)) .until(ExpectedConditions.presenceOfElementLocated(By.id("login"))) .click(); driver.findElementByAccessibilityId("webView").click(); - new WebDriverWait(driver, 30) + new WebDriverWait(driver, ofSeconds(30)) .until(ExpectedConditions.presenceOfElementLocated(MobileBy.AccessibilityId("Webview"))); findAndSwitchToWebView(); WebElement el = driver.findElementByPartialLinkText("login"); diff --git a/src/test/java/io/appium/java_client/pagefactory_tests/XCUITModeTest.java b/src/test/java/io/appium/java_client/pagefactory_tests/XCUITModeTest.java index c54bf9129..cd683709b 100644 --- a/src/test/java/io/appium/java_client/pagefactory_tests/XCUITModeTest.java +++ b/src/test/java/io/appium/java_client/pagefactory_tests/XCUITModeTest.java @@ -19,6 +19,7 @@ import static io.appium.java_client.pagefactory.LocatorGroupStrategy.ALL_POSSIBLE; import static io.appium.java_client.pagefactory.LocatorGroupStrategy.CHAIN; +import static java.time.Duration.ofSeconds; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.greaterThan; @@ -47,7 +48,7 @@ public class XCUITModeTest extends AppIOSTest { private boolean populated = false; - private WebDriverWait waiting = new WebDriverWait(driver, 10000); + private WebDriverWait waiting = new WebDriverWait(driver, ofSeconds(10000)); @HowToUseLocators(iOSXCUITAutomation = ALL_POSSIBLE) @iOSXCUITFindBy(iOSNsPredicate = "label contains 'Compute'") From 1e80399ec649606d4ebf8330250cc4782168704b Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Tue, 27 Aug 2019 13:38:44 +0200 Subject: [PATCH 003/690] fix: Avoid using getSession call for capability values retrieval (#1216) --- .../io/appium/java_client/AppiumDriver.java | 19 +++++-- .../internal/CapabilityHelpers.java | 52 +++++++++++++++++++ .../java_client/internal/ElementMap.java | 4 +- .../JsonToMobileElementConverter.java | 12 ++--- .../pagefactory/AppiumFieldDecorator.java | 49 ++++++++--------- .../utils/WebDriverUnpackUtility.java | 4 +- .../remote/NewAppiumSessionPayload.java | 2 +- .../ios/IOSNativeWebTapSettingTest.java | 1 + .../widget/tests/AbstractStubWebDriver.java | 16 +++++- .../widget/tests/ExtendedWidgetTest.java | 2 +- .../tests/android/AndroidWidgetTest.java | 2 +- .../widget/tests/ios/XCUITWidgetTest.java | 2 +- .../tests/windows/WindowsWidgetTest.java | 2 +- .../service/local/StartingAppLocallyTest.java | 2 + 14 files changed, 122 insertions(+), 47 deletions(-) create mode 100644 src/main/java/io/appium/java_client/internal/CapabilityHelpers.java diff --git a/src/main/java/io/appium/java_client/AppiumDriver.java b/src/main/java/io/appium/java_client/AppiumDriver.java index c95224da0..c0c1aca0e 100644 --- a/src/main/java/io/appium/java_client/AppiumDriver.java +++ b/src/main/java/io/appium/java_client/AppiumDriver.java @@ -19,9 +19,11 @@ import static com.google.common.base.Preconditions.checkNotNull; import static io.appium.java_client.remote.MobileCapabilityType.PLATFORM_NAME; import static org.apache.commons.lang3.StringUtils.containsIgnoreCase; +import static org.apache.commons.lang3.StringUtils.isBlank; import com.google.common.collect.ImmutableMap; +import io.appium.java_client.internal.CapabilityHelpers; import io.appium.java_client.internal.JsonToMobileElementConverter; import io.appium.java_client.remote.AppiumCommandExecutor; import io.appium.java_client.remote.MobileCapabilityType; @@ -88,7 +90,7 @@ public AppiumDriver(HttpCommandExecutor executor, Capabilities capabilities) { locationContext = new RemoteLocationContext(executeMethod); super.setErrorHandler(errorHandler); this.remoteAddress = executor.getAddressOfRemoteServer(); - this.setElementConverter(new JsonToMobileElementConverter(this, this)); + this.setElementConverter(new JsonToMobileElementConverter(this)); } public AppiumDriver(URL remoteAddress, Capabilities desiredCapabilities) { @@ -314,8 +316,19 @@ public URL getRemoteAddress() { @Override public boolean isBrowser() { - return super.isBrowser() - && !containsIgnoreCase(getContext(), "NATIVE_APP"); + String browserName = CapabilityHelpers.getCapability(getCapabilities(), "browserName", String.class); + if (!isBlank(browserName)) { + try { + return (boolean) executeScript("return !!window.navigator;"); + } catch (WebDriverException ign) { + // ignore + } + } + try { + return !containsIgnoreCase(getContext(), "NATIVE_APP"); + } catch (WebDriverException e) { + return false; + } } @Override diff --git a/src/main/java/io/appium/java_client/internal/CapabilityHelpers.java b/src/main/java/io/appium/java_client/internal/CapabilityHelpers.java new file mode 100644 index 000000000..0cb9ec96c --- /dev/null +++ b/src/main/java/io/appium/java_client/internal/CapabilityHelpers.java @@ -0,0 +1,52 @@ +/* + * 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.internal; + +import org.openqa.selenium.Capabilities; + +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.List; + +public class CapabilityHelpers { + public static final String APPIUM_PREFIX = "appium:"; + + /** + * Helper that is used for capability values retrieval. + * Supports both prefixed W3C and "classic" capability names. + * + * @param caps driver caps object + * @param name capability name + * @param expectedType the expected capability type + * @return The retrieved capability value or null if the cap either not present has an unexpected type + */ + @Nullable + public static T getCapability(Capabilities caps, String name, Class expectedType) { + List possibleNames = new ArrayList<>(); + possibleNames.add(name); + if (!name.startsWith(APPIUM_PREFIX)) { + possibleNames.add(APPIUM_PREFIX + name); + } + for (String capName : possibleNames) { + if (caps.getCapability(capName) != null + && expectedType.isAssignableFrom(caps.getCapability(capName).getClass())) { + return expectedType.cast(caps.getCapability(capName)); + } + } + return null; + } +} diff --git a/src/main/java/io/appium/java_client/internal/ElementMap.java b/src/main/java/io/appium/java_client/internal/ElementMap.java index 44c852e77..5522f7cb4 100644 --- a/src/main/java/io/appium/java_client/internal/ElementMap.java +++ b/src/main/java/io/appium/java_client/internal/ElementMap.java @@ -50,12 +50,10 @@ public enum ElementMap { mobileElementMap = builder.build(); } - - private final String platformOrAutomation; private final Class elementClass; - private ElementMap(String platformOrAutomation, Class elementClass) { + ElementMap(String platformOrAutomation, Class elementClass) { this.platformOrAutomation = platformOrAutomation; this.elementClass = elementClass; } diff --git a/src/main/java/io/appium/java_client/internal/JsonToMobileElementConverter.java b/src/main/java/io/appium/java_client/internal/JsonToMobileElementConverter.java index d78b90c7d..22cce7275 100644 --- a/src/main/java/io/appium/java_client/internal/JsonToMobileElementConverter.java +++ b/src/main/java/io/appium/java_client/internal/JsonToMobileElementConverter.java @@ -18,7 +18,7 @@ import static io.appium.java_client.internal.ElementMap.getElementClass; -import io.appium.java_client.HasSessionDetails; +import org.openqa.selenium.Capabilities; import org.openqa.selenium.WebDriverException; import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.remote.RemoteWebElement; @@ -41,20 +41,20 @@ public class JsonToMobileElementConverter extends JsonToWebElementConverter { * Creates a new instance based on {@code driver} and object with session details. * * @param driver an instance of {@link RemoteWebDriver} subclass - * @param hasSessionDetails object that has session details */ - public JsonToMobileElementConverter(RemoteWebDriver driver, HasSessionDetails hasSessionDetails) { + public JsonToMobileElementConverter(RemoteWebDriver driver) { super(driver); this.driver = driver; - this.platform = hasSessionDetails.getPlatformName(); - this.automation = hasSessionDetails.getAutomationName(); + Capabilities caps = driver.getCapabilities(); + this.platform = CapabilityHelpers.getCapability(caps, "platformName", String.class); + this.automation = CapabilityHelpers.getCapability(caps, "automationName", String.class); } @Override public Object apply(Object result) { Object toBeReturned = result; if (toBeReturned instanceof RemoteWebElement) { - toBeReturned = newRemoteWebElement(); + toBeReturned = newRemoteWebElement(); ((RemoteWebElement) toBeReturned).setId(((RemoteWebElement) result).getId()); } diff --git a/src/main/java/io/appium/java_client/pagefactory/AppiumFieldDecorator.java b/src/main/java/io/appium/java_client/pagefactory/AppiumFieldDecorator.java index febee93d6..1e651f00b 100644 --- a/src/main/java/io/appium/java_client/pagefactory/AppiumFieldDecorator.java +++ b/src/main/java/io/appium/java_client/pagefactory/AppiumFieldDecorator.java @@ -20,20 +20,22 @@ import static io.appium.java_client.pagefactory.utils.ProxyFactory.getEnhancedProxy; import static io.appium.java_client.pagefactory.utils.WebDriverUnpackUtility.unpackWebDriverFromSearchContext; import static java.time.Duration.ofSeconds; -import static java.util.Optional.ofNullable; import com.google.common.collect.ImmutableList; -import io.appium.java_client.HasSessionDetails; import io.appium.java_client.MobileElement; import io.appium.java_client.android.AndroidElement; +import io.appium.java_client.internal.CapabilityHelpers; import io.appium.java_client.ios.IOSElement; import io.appium.java_client.pagefactory.bys.ContentType; import io.appium.java_client.pagefactory.locator.CacheableLocator; import io.appium.java_client.windows.WindowsElement; +import org.openqa.selenium.Capabilities; +import org.openqa.selenium.HasCapabilities; import org.openqa.selenium.SearchContext; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; +import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.remote.RemoteWebElement; import org.openqa.selenium.support.pagefactory.DefaultFieldDecorator; import org.openqa.selenium.support.pagefactory.ElementLocator; @@ -71,30 +73,24 @@ public class AppiumFieldDecorator implements FieldDecorator { private final String automation; private final Duration duration; - /** * Creates field decorator based on {@link SearchContext} and timeout {@code duration}. * - * @param context is an instance of {@link SearchContext} - * It may be the instance of {@link WebDriver} or {@link WebElement} or - * {@link Widget} or some other user's extension/implementation. + * @param context is an instance of {@link SearchContext} + * It may be the instance of {@link WebDriver} or {@link WebElement} or + * {@link Widget} or some other user's extension/implementation. * @param duration is a desired duration of the waiting for an element presence. */ public AppiumFieldDecorator(SearchContext context, Duration duration) { this.webDriver = unpackWebDriverFromSearchContext(context); - HasSessionDetails hasSessionDetails = ofNullable(this.webDriver).map(webDriver -> { - if (!HasSessionDetails.class.isAssignableFrom(webDriver.getClass())) { - return null; - } - return HasSessionDetails.class.cast(webDriver); - }).orElse(null); - if (hasSessionDetails == null) { - platform = null; - automation = null; + if (this.webDriver instanceof HasCapabilities) { + Capabilities caps = ((HasCapabilities) this.webDriver).getCapabilities(); + this.platform = CapabilityHelpers.getCapability(caps, "platformName", String.class); + this.automation = CapabilityHelpers.getCapability(caps, "automationName", String.class); } else { - platform = hasSessionDetails.getPlatformName(); - automation = hasSessionDetails.getAutomationName(); + this.platform = null; + this.automation = null; } this.duration = duration; @@ -115,7 +111,8 @@ protected List proxyForListLocator(ClassLoader ignored, return getEnhancedProxy(ArrayList.class, elementInterceptor); } - @Override protected boolean isDecoratableList(Field field) { + @Override + protected boolean isDecoratableList(Field field) { if (!List.class.isAssignableFrom(field.getType())) { return false; } @@ -148,7 +145,7 @@ public AppiumFieldDecorator(SearchContext context) { * Decorated page object {@code field}. * * @param ignored class loader is ignored by current implementation - * @param field is {@link Field} of page object which is supposed to be decorated. + * @param field is {@link Field} of page object which is supposed to be decorated. * @return a field value or null. */ public Object decorate(ClassLoader ignored, Field field) { @@ -197,19 +194,19 @@ private Object decorateWidget(Field field) { CacheableLocator locator = widgetLocatorFactory.createLocator(field); Map> map = - OverrideWidgetReader.read(widgetType, field, platform); + OverrideWidgetReader.read(widgetType, field, platform); if (isAlist) { return getEnhancedProxy(ArrayList.class, - new WidgetListInterceptor(locator, webDriver, map, widgetType, - duration)); + new WidgetListInterceptor(locator, webDriver, map, widgetType, + duration)); } Constructor constructor = - WidgetConstructorUtil.findConvenientConstructor(widgetType); - return getEnhancedProxy(widgetType, new Class[] {constructor.getParameterTypes()[0]}, - new Object[] {proxyForAnElement(locator)}, - new WidgetInterceptor(locator, webDriver, null, map, duration)); + WidgetConstructorUtil.findConvenientConstructor(widgetType); + return getEnhancedProxy(widgetType, new Class[]{constructor.getParameterTypes()[0]}, + new Object[]{proxyForAnElement(locator)}, + new WidgetInterceptor(locator, webDriver, null, map, duration)); } private WebElement proxyForAnElement(ElementLocator locator) { diff --git a/src/main/java/io/appium/java_client/pagefactory/utils/WebDriverUnpackUtility.java b/src/main/java/io/appium/java_client/pagefactory/utils/WebDriverUnpackUtility.java index 3fc83d3e4..b15ee6775 100644 --- a/src/main/java/io/appium/java_client/pagefactory/utils/WebDriverUnpackUtility.java +++ b/src/main/java/io/appium/java_client/pagefactory/utils/WebDriverUnpackUtility.java @@ -82,7 +82,7 @@ public static WebDriver unpackWebDriverFromSearchContext(SearchContext searchCon public static ContentType getCurrentContentType(SearchContext context) { return ofNullable(unpackWebDriverFromSearchContext(context)).map(driver -> { if (HasSessionDetails.class.isAssignableFrom(driver.getClass())) { - HasSessionDetails hasSessionDetails = HasSessionDetails.class.cast(driver); + HasSessionDetails hasSessionDetails = (HasSessionDetails) driver; if (!hasSessionDetails.isBrowser()) { return NATIVE_MOBILE_SPECIFIC; @@ -90,7 +90,7 @@ public static ContentType getCurrentContentType(SearchContext context) { } if (ContextAware.class.isAssignableFrom(driver.getClass())) { //it is desktop browser - ContextAware contextAware = ContextAware.class.cast(driver); + ContextAware contextAware = (ContextAware) driver; String currentContext = contextAware.getContext(); if (containsIgnoreCase(currentContext, NATIVE_APP_PATTERN)) { return NATIVE_MOBILE_SPECIFIC; diff --git a/src/main/java/io/appium/java_client/remote/NewAppiumSessionPayload.java b/src/main/java/io/appium/java_client/remote/NewAppiumSessionPayload.java index 9ec116337..add478a87 100644 --- a/src/main/java/io/appium/java_client/remote/NewAppiumSessionPayload.java +++ b/src/main/java/io/appium/java_client/remote/NewAppiumSessionPayload.java @@ -19,6 +19,7 @@ import static com.google.common.collect.ImmutableMap.of; import static com.google.common.collect.ImmutableMap.toImmutableMap; +import static io.appium.java_client.internal.CapabilityHelpers.APPIUM_PREFIX; import static io.appium.java_client.remote.MobileCapabilityType.FORCE_MJSONWP; import static java.nio.charset.StandardCharsets.UTF_8; import static java.util.Optional.ofNullable; @@ -88,7 +89,6 @@ public class NewAppiumSessionPayload implements Closeable { .addAll(getAppiumCapabilities(AndroidMobileCapabilityType.class)) .addAll(getAppiumCapabilities(IOSMobileCapabilityType.class)) .addAll(getAppiumCapabilities(YouiEngineCapabilityType.class)).build(); - private static final String APPIUM_PREFIX = "appium:"; private static final String DESIRED_CAPABILITIES = "desiredCapabilities"; private static final String CAPABILITIES = "capabilities"; private static final String REQUIRED_CAPABILITIES = "requiredCapabilities"; diff --git a/src/test/java/io/appium/java_client/ios/IOSNativeWebTapSettingTest.java b/src/test/java/io/appium/java_client/ios/IOSNativeWebTapSettingTest.java index 25f287bc5..25746f91b 100644 --- a/src/test/java/io/appium/java_client/ios/IOSNativeWebTapSettingTest.java +++ b/src/test/java/io/appium/java_client/ios/IOSNativeWebTapSettingTest.java @@ -11,6 +11,7 @@ public class IOSNativeWebTapSettingTest extends BaseSafariTest { @Test public void nativeWebTapSettingTest() { + assertTrue(driver.isBrowser()); driver.get("https://saucelabs.com/test/guinea-pig"); // do a click with nativeWebTap turned on, and assert we get to the right page diff --git a/src/test/java/io/appium/java_client/pagefactory_tests/widget/tests/AbstractStubWebDriver.java b/src/test/java/io/appium/java_client/pagefactory_tests/widget/tests/AbstractStubWebDriver.java index 218dea51f..7e3d5783a 100644 --- a/src/test/java/io/appium/java_client/pagefactory_tests/widget/tests/AbstractStubWebDriver.java +++ b/src/test/java/io/appium/java_client/pagefactory_tests/widget/tests/AbstractStubWebDriver.java @@ -3,7 +3,6 @@ import static com.google.common.collect.ImmutableList.of; import static io.appium.java_client.remote.AutomationName.APPIUM; import static io.appium.java_client.remote.AutomationName.IOS_XCUI_TEST; -import static io.appium.java_client.remote.AutomationName.SELENDROID; import static io.appium.java_client.remote.MobilePlatform.ANDROID; import static io.appium.java_client.remote.MobilePlatform.IOS; import static io.appium.java_client.remote.MobilePlatform.WINDOWS; @@ -11,18 +10,23 @@ import io.appium.java_client.HasSessionDetails; import org.openqa.selenium.By; +import org.openqa.selenium.Capabilities; import org.openqa.selenium.Cookie; +import org.openqa.selenium.HasCapabilities; import org.openqa.selenium.WebDriver; import org.openqa.selenium.logging.Logs; +import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.remote.Response; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; -public abstract class AbstractStubWebDriver implements WebDriver, HasSessionDetails { +public abstract class AbstractStubWebDriver implements WebDriver, HasSessionDetails, + HasCapabilities { @Override public Response execute(String driverCommand, Map parameters) { return null; @@ -104,6 +108,14 @@ public Navigation navigate() { return null; } + @Override + public Capabilities getCapabilities() { + Map caps = new HashMap<>(); + caps.put("platformName", getPlatformName()); + caps.put("automationName", getAutomationName()); + return new DesiredCapabilities(caps); + } + @Override public Options manage() { return new Options() { diff --git a/src/test/java/io/appium/java_client/pagefactory_tests/widget/tests/ExtendedWidgetTest.java b/src/test/java/io/appium/java_client/pagefactory_tests/widget/tests/ExtendedWidgetTest.java index 2523c017b..d8d3a7b60 100644 --- a/src/test/java/io/appium/java_client/pagefactory_tests/widget/tests/ExtendedWidgetTest.java +++ b/src/test/java/io/appium/java_client/pagefactory_tests/widget/tests/ExtendedWidgetTest.java @@ -24,7 +24,7 @@ protected ExtendedWidgetTest(ExtendedApp app, WebDriver driver) { public abstract void checkCaseWhenWidgetClassHasNoDeclaredAnnotationButItHasSuperclass(); @Test - public abstract void checkCaseWhenBothWidgetFieldAndClassHaveDelaredAnnotations(); + public abstract void checkCaseWhenBothWidgetFieldAndClassHaveDeclaredAnnotations(); protected static void checkThatLocatorsAreCreatedCorrectly(DefaultStubWidget single, List multiple, By rootLocator, diff --git a/src/test/java/io/appium/java_client/pagefactory_tests/widget/tests/android/AndroidWidgetTest.java b/src/test/java/io/appium/java_client/pagefactory_tests/widget/tests/android/AndroidWidgetTest.java index 7985e67c4..3b94b21cd 100644 --- a/src/test/java/io/appium/java_client/pagefactory_tests/widget/tests/android/AndroidWidgetTest.java +++ b/src/test/java/io/appium/java_client/pagefactory_tests/widget/tests/android/AndroidWidgetTest.java @@ -37,7 +37,7 @@ public void checkCaseWhenWidgetClassHasNoDeclaredAnnotationButItHasSuperclass() } @Override - public void checkCaseWhenBothWidgetFieldAndClassHaveDelaredAnnotations() { + public void checkCaseWhenBothWidgetFieldAndClassHaveDeclaredAnnotations() { checkThatLocatorsAreCreatedCorrectly(((ExtendedApp) app).getExtendedWidgetWithOverriddenLocators(), ((ExtendedApp) app).getExtendedWidgetsWithOverriddenLocators(), AndroidUIAutomator(ANDROID_EXTERNALLY_DEFINED_WIDGET_LOCATOR), diff --git a/src/test/java/io/appium/java_client/pagefactory_tests/widget/tests/ios/XCUITWidgetTest.java b/src/test/java/io/appium/java_client/pagefactory_tests/widget/tests/ios/XCUITWidgetTest.java index 6c1e4a1de..56abc937a 100644 --- a/src/test/java/io/appium/java_client/pagefactory_tests/widget/tests/ios/XCUITWidgetTest.java +++ b/src/test/java/io/appium/java_client/pagefactory_tests/widget/tests/ios/XCUITWidgetTest.java @@ -37,7 +37,7 @@ public void checkCaseWhenWidgetClassHasNoDeclaredAnnotationButItHasSuperclass() } @Override - public void checkCaseWhenBothWidgetFieldAndClassHaveDelaredAnnotations() { + public void checkCaseWhenBothWidgetFieldAndClassHaveDeclaredAnnotations() { checkThatLocatorsAreCreatedCorrectly(((ExtendedApp) app).getExtendedWidgetWithOverriddenLocators(), ((ExtendedApp) app).getExtendedWidgetsWithOverriddenLocators(), iOSNsPredicateString(XCUIT_EXTERNALLY_DEFINED_WIDGET_LOCATOR), diff --git a/src/test/java/io/appium/java_client/pagefactory_tests/widget/tests/windows/WindowsWidgetTest.java b/src/test/java/io/appium/java_client/pagefactory_tests/widget/tests/windows/WindowsWidgetTest.java index 5358b29dc..fbd9da9a6 100644 --- a/src/test/java/io/appium/java_client/pagefactory_tests/widget/tests/windows/WindowsWidgetTest.java +++ b/src/test/java/io/appium/java_client/pagefactory_tests/widget/tests/windows/WindowsWidgetTest.java @@ -37,7 +37,7 @@ public void checkCaseWhenWidgetClassHasNoDeclaredAnnotationButItHasSuperclass() } @Override - public void checkCaseWhenBothWidgetFieldAndClassHaveDelaredAnnotations() { + public void checkCaseWhenBothWidgetFieldAndClassHaveDeclaredAnnotations() { checkThatLocatorsAreCreatedCorrectly(((ExtendedApp) app).getExtendedWidgetWithOverriddenLocators(), ((ExtendedApp) app).getExtendedWidgetsWithOverriddenLocators(), windowsAutomation(WINDOWS_EXTERNALLY_DEFINED_WIDGET_LOCATOR), diff --git a/src/test/java/io/appium/java_client/service/local/StartingAppLocallyTest.java b/src/test/java/io/appium/java_client/service/local/StartingAppLocallyTest.java index ab7c1d912..1ffecff14 100644 --- a/src/test/java/io/appium/java_client/service/local/StartingAppLocallyTest.java +++ b/src/test/java/io/appium/java_client/service/local/StartingAppLocallyTest.java @@ -18,6 +18,7 @@ import static io.github.bonigarcia.wdm.WebDriverManager.chromedriver; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -197,6 +198,7 @@ public class StartingAppLocallyTest { assertTrue(caps.getCapability(MobileCapabilityType.PLATFORM_NAME) .toString().equalsIgnoreCase(MobilePlatform.IOS)); assertNotEquals(null, caps.getCapability(MobileCapabilityType.DEVICE_NAME)); + assertFalse(driver.isBrowser()); } finally { driver.quit(); } From 41b4f28623df0865980bbee3db5d53a60a91a18b Mon Sep 17 00:00:00 2001 From: Srinivasan Sekar Date: Tue, 27 Aug 2019 21:28:11 +0530 Subject: [PATCH 004/690] update changelog and version to latest --- README.md | 11 +++++++++++ build.gradle | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f5bf5e592..ba0e11a1a 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,17 @@ dependencies { ``` ## Changelog +*7.2.0* +- **[DEPENDENCY UPDATES]** + - `org.seleniumhq.selenium:selenium-java` was reverted to stable version 3.141.59. [#1209](https://github.com/appium/java-client/pull/1209) + - `org.projectlombok:lombok:1.18.8` was introduced. [#1193](https://github.com/appium/java-client/pull/1193) +- **[ENHANCEMENTS]** + - `videoFilters` property was added to IOSStartScreenRecordingOptions. [#1180](https://github.com/appium/java-client/pull/1180) +- **[IMPROVEMENTS]** + - `Selendroid` automationName was deprecated. [#1198](https://github.com/appium/java-client/pull/1198) + - JavaDocs for AndroidMobileCapabilityType and IOSMobileCapabilityType were updated. [#1204](https://github.com/appium/java-client/pull/1204) + - JitPack builds were fixed. [#1203](https://github.com/appium/java-client/pull/1203) + *7.1.0* - **[ENHANCEMENTS]** - Added an ability to get all the session details. [#1167 ](https://github.com/appium/java-client/pull/1167) diff --git a/build.gradle b/build.gradle index 04a68df9f..34437104b 100644 --- a/build.gradle +++ b/build.gradle @@ -136,7 +136,7 @@ publishing { mavenJava(MavenPublication) { groupId = 'io.appium' artifactId = 'java-client' - version = '7.1.0' + version = '7.2.0' from components.java artifact sourcesJar artifact javadocJar From 136afba9f8dcc7afae0dbb4490188ad3be48a276 Mon Sep 17 00:00:00 2001 From: Srinivasan Sekar Date: Wed, 28 Aug 2019 11:56:46 +0530 Subject: [PATCH 005/690] Github Actions (#1219) * Try Github Actions * Remove travis --- .github/workflows/gradle.yml | 17 +++++++++++++++++ .travis.yml | 28 ---------------------------- 2 files changed, 17 insertions(+), 28 deletions(-) create mode 100644 .github/workflows/gradle.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml new file mode 100644 index 000000000..04241b76f --- /dev/null +++ b/.github/workflows/gradle.yml @@ -0,0 +1,17 @@ +name: Appium Java Client CI + +on: [push, pull_request] + +jobs: + build: + + runs-on: macOS-latest + + steps: + - uses: actions/checkout@v1 + - name: Set up JDK 1.8 + uses: actions/setup-java@v1 + with: + java-version: 1.8 + - name: Build with Gradle + run: ./gradlew clean build -x signMavenJavaPublication -x test -x checkstyleTest diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 062d09d79..000000000 --- a/.travis.yml +++ /dev/null @@ -1,28 +0,0 @@ -sudo: required - -matrix: - include: - - language: android - install: - - echo y | android update sdk -u -a -t tools - - echo y | android update sdk -u -a -t platform-tools - - echo y | android update sdk -u -a -t build-tools-25.0.2 - - echo y | android update sdk -u -a -t android-25 - - echo y | android update sdk -u -a -t extra-google-m2repository - - echo y | android update sdk -u -a -t extra-android-m2repository - os: linux - jdk: oraclejdk8 - android: - components: - - extra-android-support - - sys-img-armeabi-v7a-android-24 - script: - - ./gradlew clean build -x signMavenJavaPublication -x test -x checkstyleTest - -before_cache: - - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock - - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ -cache: - directories: - - $HOME/.gradle/caches/ - - $HOME/.gradle/wrapper/ From 9020174c578bed5e03c24b43c2c5ba590f663201 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Sat, 7 Sep 2019 13:18:04 +0200 Subject: [PATCH 006/690] fix: Fix the return type for getSystemBars call (#1230) --- .../android/HasAndroidDeviceDetails.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/java/io/appium/java_client/android/HasAndroidDeviceDetails.java b/src/main/java/io/appium/java_client/android/HasAndroidDeviceDetails.java index 03006185e..7984a0b43 100644 --- a/src/main/java/io/appium/java_client/android/HasAndroidDeviceDetails.java +++ b/src/main/java/io/appium/java_client/android/HasAndroidDeviceDetails.java @@ -10,17 +10,21 @@ public interface HasAndroidDeviceDetails extends ExecutesMethod { - /* - Retrieve the display density of the Android device. + /** + Retrieve the display density of the Android device. + + @return The density value in dpi */ default Long getDisplayDensity() { return CommandExecutionHelper.execute(this, getDisplayDensityCommand()); } - /* - Retrieve visibility and bounds information of the status and navigation bars. + /** + Retrieve visibility and bounds information of the status and navigation bars. + + @return The map where keys are bar types and values are mappings of bar properties. */ - default Map getSystemBars() { + default Map> getSystemBars() { return CommandExecutionHelper.execute(this, getSystemBarsCommand()); } From 822f0043d51ed5c15897216d6deac5821ec3913b Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Sat, 7 Sep 2019 13:18:30 +0200 Subject: [PATCH 007/690] chore: Switch the implementation of backgroundApp for iOS, so it's in sync with other platforms (#1229) --- .../io/appium/java_client/InteractsWithApps.java | 9 +++++---- .../java/io/appium/java_client/ios/IOSDriver.java | 15 --------------- 2 files changed, 5 insertions(+), 19 deletions(-) diff --git a/src/main/java/io/appium/java_client/InteractsWithApps.java b/src/main/java/io/appium/java_client/InteractsWithApps.java index f0624db4a..202360e22 100644 --- a/src/main/java/io/appium/java_client/InteractsWithApps.java +++ b/src/main/java/io/appium/java_client/InteractsWithApps.java @@ -95,13 +95,14 @@ default void resetApp() { /** * Runs the current app as a background app for the time - * requested. This is a synchronous method, it returns after the back has - * been returned to the foreground. + * requested. This is a synchronous method, it blocks while the + * application is in background. * - * @param duration The time to run App in background. Minimum time resolution is one second + * @param duration The time to run App in background. Minimum time resolution is one millisecond. + * Passing zero or a negative value will switch to Home screen and return immediately. */ default void runAppInBackground(Duration duration) { - execute(RUN_APP_IN_BACKGROUND, ImmutableMap.of("seconds", duration.getSeconds())); + execute(RUN_APP_IN_BACKGROUND, ImmutableMap.of("seconds", duration.toMillis() / 1000.0)); } /** 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 1d668c5de..229aac70b 100644 --- a/src/main/java/io/appium/java_client/ios/IOSDriver.java +++ b/src/main/java/io/appium/java_client/ios/IOSDriver.java @@ -16,7 +16,6 @@ package io.appium.java_client.ios; -import static io.appium.java_client.MobileCommand.RUN_APP_IN_BACKGROUND; import static io.appium.java_client.MobileCommand.prepareArguments; import static org.openqa.selenium.remote.DriverCommand.EXECUTE_SCRIPT; @@ -43,7 +42,6 @@ import org.openqa.selenium.remote.http.HttpClient; import java.net.URL; -import java.time.Duration; import java.util.Collections; import java.util.Map; @@ -169,19 +167,6 @@ public IOSDriver(Capabilities desiredCapabilities) { super(updateDefaultPlatformName(desiredCapabilities, IOS_DEFAULT_PLATFORM)); } - /** - * Runs the current app as a background app for the number of seconds - * or minimizes the app. - * - * @param duration The time to run App in background. - */ - @Override public void runAppInBackground(Duration duration) { - // timeout parameter is expected to be in milliseconds - // float values are allowed - execute(RUN_APP_IN_BACKGROUND, - prepareArguments("seconds", prepareArguments("timeout", duration.toMillis()))); - } - @Override public TargetLocator switchTo() { return new InnerTargetLocator(); } From 9fb06b159a303f9e2ed93ab4d88ddac617f079fe Mon Sep 17 00:00:00 2001 From: JamesSassano <51380750+JamesSassano@users.noreply.github.com> Date: Mon, 16 Sep 2019 01:35:19 -0400 Subject: [PATCH 008/690] fix: Page factory list element not initialized when parameterized by generic type (#1237) --- .../pagefactory/AppiumFieldDecorator.java | 8 + .../pagefactory_tests/GenericTest.java | 237 ++++++++++++++++-- 2 files changed, 224 insertions(+), 21 deletions(-) diff --git a/src/main/java/io/appium/java_client/pagefactory/AppiumFieldDecorator.java b/src/main/java/io/appium/java_client/pagefactory/AppiumFieldDecorator.java index 1e651f00b..933795729 100644 --- a/src/main/java/io/appium/java_client/pagefactory/AppiumFieldDecorator.java +++ b/src/main/java/io/appium/java_client/pagefactory/AppiumFieldDecorator.java @@ -45,8 +45,10 @@ import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; import java.time.Duration; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Map; @@ -129,6 +131,12 @@ protected boolean isDecoratableList(Field field) { return true; } } + + if ((listType instanceof TypeVariable) + && Arrays.asList(((TypeVariable) listType).getBounds()) + .stream().anyMatch(item -> availableElementClasses.contains(item))) { + return true; + } return false; } }; diff --git a/src/test/java/io/appium/java_client/pagefactory_tests/GenericTest.java b/src/test/java/io/appium/java_client/pagefactory_tests/GenericTest.java index 7c06ba2a5..16e83e2fe 100644 --- a/src/test/java/io/appium/java_client/pagefactory_tests/GenericTest.java +++ b/src/test/java/io/appium/java_client/pagefactory_tests/GenericTest.java @@ -1,30 +1,156 @@ package io.appium.java_client.pagefactory_tests; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import io.appium.java_client.pagefactory.AppiumFieldDecorator; +import io.appium.java_client.remote.AutomationName; +import io.appium.java_client.remote.MobileCapabilityType; + +import org.apache.commons.lang3.NotImplementedException; import org.junit.Test; import org.openqa.selenium.By; +import org.openqa.selenium.Capabilities; +import org.openqa.selenium.HasCapabilities; +import org.openqa.selenium.Platform; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; +import org.openqa.selenium.remote.CapabilityType; import org.openqa.selenium.support.PageFactory; +import io.appium.java_client.MobileElement; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Set; -import java.util.function.Supplier; public class GenericTest { - static class TempGenericPage { + /** + * The Generic types are null on an unbound page. + */ + private static void assertUnboundGenericsNull(T genericItem, + List genericItems) { + assertNull(genericItem); + assertNull(genericItems); + } + + /** + * The Generic types are not null on a page bound by a WebElement (or WebElement + * sub type). + */ + private static void assertBoundGenericsNotNull(T genericItem, + List genericItems) { + assertNotNull(genericItem); + assertNotNull(genericItems); + } + + /** + * The Element types are never null. + */ + private static void assertElementsNotNull(WebElement elementItem, + List elementItems) { + assertNotNull(elementItem); + assertNotNull(elementItems); + } + + /** + * The Object types are always null. + */ + private static void assertObjectsNull(Object objectItem, List objectItems) { + assertNull(objectItem); + assertNull(objectItems); + } + + /** + * A page with no generic types. The Object types are never initialized. + */ + static class TempNoGenericsPage { + public WebElement webElementItem; + public MobileElement mobileElementItem; + public Object objectItem; + + public List webElementItems; + public List mobileElementItems; + public List objectItems; + + public void assertInit() { + assertElementsNotNull(webElementItem, webElementItems); + assertElementsNotNull(mobileElementItem, mobileElementItems); + assertObjectsNull(objectItem, objectItems); + } + } + + /** + * A page with an unbound generic type. The generic and Object types are never + * initialized. + */ + static class TempUnboundPage { + public T genericItem; + public WebElement webElementItem; + public MobileElement mobileElementItem; + public Object objectItem; - public List items; + public List genericItems; + public List webElementItems; + public List mobileElementItems; + public List objectItems; - public List getItems() { - return items; + public void assertInit() { + assertUnboundGenericsNull(genericItem, genericItems); + assertElementsNotNull(webElementItem, webElementItems); + assertElementsNotNull(mobileElementItem, mobileElementItems); + assertObjectsNull(objectItem, objectItems); } } - static class MockWebDriver implements WebDriver { + /** + * A page with a WebElement bound generic type. The Object types are never + * initialized. + */ + static class TempWebBoundPage { + public T genericItem; + public WebElement webElementItem; + public MobileElement mobileElementItem; + public Object objectItem; + + public List genericItems; + public List webElementItems; + public List mobileElementItems; + public List objectItems; + + public void assertInit() { + assertBoundGenericsNotNull(genericItem, genericItems); + assertElementsNotNull(webElementItem, webElementItems); + assertElementsNotNull(mobileElementItem, mobileElementItems); + assertObjectsNull(objectItem, objectItems); + } + } + + /** + * A page with a MobileElement bound generic type. The Object types are never + * initialized. + */ + static class TempMobileBoundPage { + public T genericItem; + public WebElement webElementItem; + public MobileElement mobileElementItem; + public Object objectItem; + + public List genericItems; + public List webElementItems; + public List mobileElementItems; + public List objectItems; + + public void assertInit() { + assertBoundGenericsNotNull(genericItem, genericItems); + assertElementsNotNull(webElementItem, webElementItems); + assertElementsNotNull(mobileElementItem, mobileElementItems); + assertObjectsNull(objectItem, objectItems); + } + } + + static class MockWebDriver implements WebDriver, HasCapabilities { @Override public void get(String url) { @@ -42,13 +168,13 @@ public String getTitle() { } @Override - public List findElements(By by) { - return null; + public List findElements(By by) { + throw new NotImplementedException("MockWebDriver did not expect to findElements"); } @Override - public WebElement findElement(By by) { - return null; + public T findElement(By by) { + throw new NotImplementedException("MockWebDriver did not expect to findElement"); } @Override @@ -90,16 +216,85 @@ public Navigation navigate() { public Options manage() { return null; } + + @Override + public Capabilities getCapabilities() { + + final Map capabilities = new HashMap<>(); + + // These are needed to map the proxy element to a MobileElement. + capabilities.put(CapabilityType.PLATFORM_NAME, Platform.ANY.toString()); + capabilities.put(MobileCapabilityType.AUTOMATION_NAME, + AutomationName.IOS_XCUI_TEST.toString()); + + return new Capabilities() { + + @Override + public Object getCapability(String capabilityName) { + return capabilities.get(capabilityName); + } + + @Override + public Map asMap() { + return capabilities; + } + }; + } + } + + @Test + public void noGenericsTestCase() { + TempNoGenericsPage page = new TempNoGenericsPage(); + PageFactory.initElements(new AppiumFieldDecorator(new MockWebDriver()), page); + page.assertInit(); + } + + @Test + public void unBoundTestCase() { + TempUnboundPage page = new TempUnboundPage<>(); + PageFactory.initElements(new AppiumFieldDecorator(new MockWebDriver()), page); + page.assertInit(); + } + + @Test + public void unboundWebElementTestCase() { + TempUnboundPage page = new TempUnboundPage<>(); + PageFactory.initElements(new AppiumFieldDecorator(new MockWebDriver()), page); + page.assertInit(); + } + + @Test + public void webBoundUnknownElementTestCase() { + TempWebBoundPage page = new TempWebBoundPage<>(); + PageFactory.initElements(new AppiumFieldDecorator(new MockWebDriver()), page); + page.assertInit(); + } + + @Test + public void webBoundWebElementTestCase() { + TempWebBoundPage page = new TempWebBoundPage<>(); + PageFactory.initElements(new AppiumFieldDecorator(new MockWebDriver()), page); + page.assertInit(); } @Test - public void genericTestCse() { - Supplier result = () -> { - PageFactory - .initElements(new AppiumFieldDecorator(new MockWebDriver()), - new TempGenericPage<>()); - return true; - }; - assertTrue(result.get()); - } -} \ No newline at end of file + public void webBoundMobileElementTestCase() { + TempWebBoundPage page = new TempWebBoundPage<>(); + PageFactory.initElements(new AppiumFieldDecorator(new MockWebDriver()), page); + page.assertInit(); + } + + @Test + public void mobileBoundUnknownElementTestCase() { + TempMobileBoundPage page = new TempMobileBoundPage<>(); + PageFactory.initElements(new AppiumFieldDecorator(new MockWebDriver()), page); + page.assertInit(); + } + + @Test + public void mobileBoundMobileElementTestCase() { + TempMobileBoundPage page = new TempMobileBoundPage<>(); + PageFactory.initElements(new AppiumFieldDecorator(new MockWebDriver()), page); + page.assertInit(); + } +} From e19ac644699daf8cc6746f37a1bd86fb3c705e16 Mon Sep 17 00:00:00 2001 From: a-en Date: Tue, 17 Sep 2019 20:15:36 +0300 Subject: [PATCH 009/690] Update AndroidMobileCapabilityType (#1238) * missing capabilities added * minor updates * fixed checkstyle complaints * for list of caps added version since cap is available * changed description for 'autoLaunch' capability --- .../remote/AndroidMobileCapabilityType.java | 174 +++++++++++++++++- 1 file changed, 173 insertions(+), 1 deletion(-) diff --git a/src/main/java/io/appium/java_client/remote/AndroidMobileCapabilityType.java b/src/main/java/io/appium/java_client/remote/AndroidMobileCapabilityType.java index ad1a792ec..a73e9075f 100644 --- a/src/main/java/io/appium/java_client/remote/AndroidMobileCapabilityType.java +++ b/src/main/java/io/appium/java_client/remote/AndroidMobileCapabilityType.java @@ -57,6 +57,7 @@ public interface AndroidMobileCapabilityType extends CapabilityType { /** * Timeout in milliseconds used to wait for the appWaitActivity to launch (default 20000). + * @since 1.6.0 */ String APP_WAIT_DURATION = "appWaitDuration"; @@ -65,12 +66,24 @@ public interface AndroidMobileCapabilityType extends CapabilityType { */ String DEVICE_READY_TIMEOUT = "deviceReadyTimeout"; + /** + * Allow to install a test package which has {@code android:testOnly="true"} in the manifest. + * {@code false} by default + */ + String ALLOW_TEST_PACKAGES = "allowTestPackages"; + /** * Fully qualified instrumentation class. Passed to -w in adb shell * am instrument -e coverage true -w. */ String ANDROID_COVERAGE = "androidCoverage"; + /** + * A broadcast action implemented by yourself which is used to dump coverage into file system. + * Passed to -a in adb shell am broadcast -a + */ + String ANDROID_COVERAGE_END_INTENT = "androidCoverageEndIntent"; + /** * (Chrome and webview only) Enable Chromedriver's performance logging (default false). * @@ -97,9 +110,17 @@ public interface AndroidMobileCapabilityType extends CapabilityType { /** * Timeout in milliseconds used to wait for an apk to install to the device. Defaults to `90000`. + * @since 1.6.0 */ String ANDROID_INSTALL_TIMEOUT = "androidInstallTimeout"; + /** + * The name of the directory on the device in which the apk will be push before install. + * Defaults to {@code /data/local/tmp} + * @since 1.6.5 + */ + String ANDROID_INSTALL_PATH = "androidInstallPath"; + /** * Name of avd to launch. */ @@ -108,12 +129,14 @@ public interface AndroidMobileCapabilityType extends CapabilityType { /** * How long to wait in milliseconds for an avd to launch and connect to * ADB (default 120000). + * @since 0.18.0 */ String AVD_LAUNCH_TIMEOUT = "avdLaunchTimeout"; /** * How long to wait in milliseconds for an avd to finish its * boot animations (default 120000). + * @since 0.18.0 */ String AVD_READY_TIMEOUT = "avdReadyTimeout"; @@ -154,8 +177,59 @@ public interface AndroidMobileCapabilityType extends CapabilityType { */ String CHROMEDRIVER_EXECUTABLE = "chromedriverExecutable"; + /** + * An array of arguments to be passed to the chromedriver binary when it's run by Appium. + * By default no CLI args are added beyond what Appium uses internally (such as {@code --url-base}, {@code --port}, + * {@code --adb-port}, and {@code --log-path}. + * @since 1.12.0 + */ + String CHROMEDRIVER_ARGS = "chromedriverArgs"; + + /** + * The absolute path to a directory to look for Chromedriver executables in, for automatic discovery of compatible + * Chromedrivers. Ignored if {@code chromedriverUseSystemExecutable} is {@code true} + * @since 1.8.0 + */ + String CHROMEDRIVER_EXECUTABLE_DIR = "chromedriverExecutableDir"; + + /** + * The absolute path to a file which maps Chromedriver versions to the minimum Chrome that it supports. + * Ignored if {@code chromedriverUseSystemExecutable} is {@code true} + * @since 1.8.0 + */ + String CHROMEDRIVER_CHROME_MAPPING_FILE = "chromedriverChromeMappingFile"; + + /** + * If true, bypasses automatic Chromedriver configuration and uses the version that comes downloaded with Appium. + * Ignored if {@code chromedriverExecutable} is set. Defaults to {@code false} + * @since 1.9.0 + */ + String CHROMEDRIVER_USE_SYSTEM_EXECUTABLE = "chromedriverUseSystemExecutable"; + + /** + * Numeric port to start Chromedriver on. Note that use of this capability is discouraged as it will cause undefined + * behavior in case there are multiple webviews present. By default Appium will find a free port. + */ + String CHROMEDRIVER_PORT = "chromedriverPort"; + + /** + * A list of valid ports for Appium to use for communication with Chromedrivers. This capability supports multiple + * webview scenarios. The form of this capability is an array of numeric ports, where array items can themselves be + * arrays of length 2, where the first element is the start of an inclusive range and the second is the end. + * By default, Appium will use any free port. + * @since 1.13.0 + */ + String CHROMEDRIVER_PORTS = "chromedriverPorts"; + + /** + * Sets the chromedriver flag {@code --disable-build-check} for Chrome webview tests. + * @since 1.11.0 + */ + String CHROMEDRIVER_DISABLE_BUILD_CHECK = "chromedriverDisableBuildCheck"; + /** * Amount of time to wait for Webview context to become active, in ms. Defaults to 2000. + * @since 1.5.2 */ String AUTO_WEBVIEW_TIMEOUT = "autoWebviewTimeout"; @@ -190,11 +264,13 @@ public interface AndroidMobileCapabilityType extends CapabilityType { * the test app using adb. In other words, with dontStopAppOnReset set to true, * we will not include the -S flag in the adb shell am start call. * With this capability omitted or set to false, we include the -S flag. Default false + * @since 1.4.0 */ String DONT_STOP_APP_ON_RESET = "dontStopAppOnReset"; /** * Enable Unicode input, default false. + * @since 1.2.0 */ String UNICODE_KEYBOARD = "unicodeKeyboard"; @@ -207,6 +283,7 @@ public interface AndroidMobileCapabilityType extends CapabilityType { /** * Skip checking and signing of app with debug keys, will work only with * UiAutomator and not with selendroid, default false. + * @since 1.2.2 */ String NO_SIGN = "noSign"; @@ -223,6 +300,7 @@ public interface AndroidMobileCapabilityType extends CapabilityType { * Disables android watchers that watch for application not responding and application crash, * this will reduce cpu usage on android device/emulator. This capability will work only with * UiAutomator and not with selendroid, default false. + * @since 1.4.0 */ String DISABLE_ANDROID_WATCHERS = "disableAndroidWatchers"; @@ -243,18 +321,57 @@ public interface AndroidMobileCapabilityType extends CapabilityType { /** * In a web context, use native (adb) method for taking a screenshot, rather than proxying * to ChromeDriver, default false. + * @since 1.5.3 */ String NATIVE_WEB_SCREENSHOT = "nativeWebScreenshot"; /** * The name of the directory on the device in which the screenshot will be put. * Defaults to /data/local/tmp. + * @since 1.6.0 */ String ANDROID_SCREENSHOT_PATH = "androidScreenshotPath"; + /** + * Set the network speed emulation. Specify the maximum network upload and download speeds. Defaults to {@code full} + */ + String NETWORK_SPEED = "networkSpeed"; + + /** + * Toggle gps location provider for emulators before starting the session. By default the emulator will have this + * option enabled or not according to how it has been provisioned. + */ + String GPS_ENABLED = "gpsEnabled"; + + /** + * Set this capability to {@code true} to run the Emulator headless when device display is not needed to be visible. + * {@code false} is the default value. isHeadless is also support for iOS, check XCUITest-specific capabilities. + */ + String IS_HEADLESS = "isHeadless"; + + /** + * Timeout in milliseconds used to wait for adb command execution. Defaults to {@code 20000} + */ + String ADB_EXEC_TIMEOUT = "adbExecTimeout"; + + /** + * Sets the locale for more details. */ String SYSTEM_PORT = "systemPort"; + + /** + * Optional remote ADB server host. + * @since 1.7.0 + */ + String REMOTE_ADB_HOST = "remoteAdbHost"; + + /** + * Skips unlock during session creation. Defaults to {@code false} + */ + String SKIP_UNLOCK = "skipUnlock"; + + /** + * Unlock the target device with particular lock pattern instead of just waking up the device with a helper app. + * It works with {@code unlockKey} capability. Defaults to undefined. {@code fingerprint} is available only for + * Android 6.0+ and emulators. + * Read unlock doc in + * android driver. + */ + String UNLOCK_TYPE = "unlockType"; + + /** + * A key pattern to unlock used by {@code unlockType}. + */ + String UNLOCK_KEY = "unlockKey"; + + /** + * Initializing the app under test automatically. + * Appium does not launch the app under test if this is {@code false}. Defaults to {@code true} + */ + String AUTO_LAUNCH = "autoLaunch"; + + /** + * Skips to start capturing logcat. It might improve performance such as network. + * Log related commands will not work. Defaults to {@code false}. + * @since 1.12.0 + */ + String SKIP_LOGCAT_CAPTURE = "skipLogcatCapture"; + + /** + * A package, list of packages or * to uninstall package/s before installing apks for test. + * {@code '*'} uninstall all of thrid-party packages except for packages which is necessary for Appium to test such + * as {@code io.appium.settings} or {@code io.appium.uiautomator2.server} since Appium already contains the logic to + * manage them. + * @since 1.12.0 + */ + String UNINSTALL_OTHER_PACKAGES = "uninstallOtherPackages"; + + /** + * Set device animation scale zero if the value is {@code true}. After session is complete, Appium restores the + * animation scale to it's original value. Defaults to {@code false} + * @since 1.9.0 + */ + String DISABLE_WINDOW_ANIMATION = "disableWindowAnimation"; } From f11fe00a536d6c6a81eeb3b0d130607572b0887e Mon Sep 17 00:00:00 2001 From: Takeshi Kishi Date: Tue, 24 Sep 2019 01:59:16 +0900 Subject: [PATCH 010/690] feat: Make settings api to accept string names (#1240) --- src/main/java/io/appium/java_client/HasSettings.java | 12 ++++++++++++ .../java/io/appium/java_client/MobileCommand.java | 4 ++-- .../io/appium/java_client/android/SettingTest.java | 11 +++++++++++ .../java/io/appium/java_client/ios/SettingTest.java | 11 +++++++++++ 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/main/java/io/appium/java_client/HasSettings.java b/src/main/java/io/appium/java_client/HasSettings.java index 3195bcf58..4a8bdfbff 100644 --- a/src/main/java/io/appium/java_client/HasSettings.java +++ b/src/main/java/io/appium/java_client/HasSettings.java @@ -37,6 +37,18 @@ public interface HasSettings extends ExecutesMethod { * @param value value of the setting. */ default void setSetting(Setting setting, Object value) { + CommandExecutionHelper.execute(this, setSettingsCommand(setting.toString(), value)); + } + + /** + * Set a setting for this test session It's probably better to use a + * convenience function, rather than use this function directly. Try finding + * the method for the specific setting you want to change. + * + * @param setting Setting you wish to set. + * @param value value of the setting. + */ + default void setSetting(String setting, Object value) { CommandExecutionHelper.execute(this, setSettingsCommand(setting, value)); } diff --git a/src/main/java/io/appium/java_client/MobileCommand.java b/src/main/java/io/appium/java_client/MobileCommand.java index aaf855468..ab0d3d756 100644 --- a/src/main/java/io/appium/java_client/MobileCommand.java +++ b/src/main/java/io/appium/java_client/MobileCommand.java @@ -469,9 +469,9 @@ public static ImmutableMap prepareArguments(String[] params, return new AbstractMap.SimpleEntry<>(GET_SETTINGS, ImmutableMap.of()); } - public static Map.Entry> setSettingsCommand(Setting setting, Object value) { + public static Map.Entry> setSettingsCommand(String setting, Object value) { return new AbstractMap.SimpleEntry<>(SET_SETTINGS, prepareArguments("settings", - prepareArguments(setting.toString(), value))); + prepareArguments(setting, value))); } /** diff --git a/src/test/java/io/appium/java_client/android/SettingTest.java b/src/test/java/io/appium/java_client/android/SettingTest.java index 0cd0ac6f5..559c1ba69 100644 --- a/src/test/java/io/appium/java_client/android/SettingTest.java +++ b/src/test/java/io/appium/java_client/android/SettingTest.java @@ -92,6 +92,17 @@ public class SettingTest extends BaseAndroidTest { .get(Setting.TRACK_SCROLL_EVENTS.toString())); } + @Test public void testSettingByString() { + assertEquals(true, driver.getSettings() + .get("shouldUseCompactResponses")); + driver.setSetting("shouldUseCompactResponses", false); + assertEquals(false, driver.getSettings() + .get("shouldUseCompactResponses")); + driver.setSetting("shouldUseCompactResponses", true); + assertEquals(true, driver.getSettings() + .get("shouldUseCompactResponses")); + } + private void assertJSONElementContains(Setting setting, long value) { assertEquals(driver.getSettings().get(setting.toString()), value); } diff --git a/src/test/java/io/appium/java_client/ios/SettingTest.java b/src/test/java/io/appium/java_client/ios/SettingTest.java index b6d576585..d48d2c64d 100644 --- a/src/test/java/io/appium/java_client/ios/SettingTest.java +++ b/src/test/java/io/appium/java_client/ios/SettingTest.java @@ -83,5 +83,16 @@ public class SettingTest extends AppIOSTest { .get(Setting.KEYBOARD_PREDICTION.toString())); } + @Test public void testSettingByString() { + assertEquals(true, driver.getSettings() + .get("shouldUseCompactResponses")); + driver.setSetting("shouldUseCompactResponses", false); + assertEquals(false, driver.getSettings() + .get("shouldUseCompactResponses")); + driver.setSetting("shouldUseCompactResponses", true); + assertEquals(true, driver.getSettings() + .get("shouldUseCompactResponses")); + } + } From 53814cd5ac77cf26e73c89eee49649af39f9c5a5 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Tue, 24 Sep 2019 07:26:23 +0200 Subject: [PATCH 011/690] fix: Avoid throwing null pointer exception if any of settings is equal to null (#1241) --- src/main/java/io/appium/java_client/HasSettings.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/io/appium/java_client/HasSettings.java b/src/main/java/io/appium/java_client/HasSettings.java index 4a8bdfbff..2db441b57 100644 --- a/src/main/java/io/appium/java_client/HasSettings.java +++ b/src/main/java/io/appium/java_client/HasSettings.java @@ -63,8 +63,6 @@ default void setSetting(String setting, Object value) { default Map getSettings() { Map.Entry> keyValuePair = getSettingsCommand(); Response response = execute(keyValuePair.getKey(), keyValuePair.getValue()); - - return ImmutableMap.builder() - .putAll(Map.class.cast(response.getValue())).build(); + return (Map) response.getValue(); } } From 5aa800994d87607ac1e21aab8273bde6dd1b2ea2 Mon Sep 17 00:00:00 2001 From: Mori Atsushi Date: Sat, 5 Oct 2019 23:24:13 +0900 Subject: [PATCH 012/690] Fix typo (#1250) --- .../io/appium/java_client/android/nativekey/AndroidKey.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/io/appium/java_client/android/nativekey/AndroidKey.java b/src/main/java/io/appium/java_client/android/nativekey/AndroidKey.java index fb82b1abc..c0a809801 100644 --- a/src/main/java/io/appium/java_client/android/nativekey/AndroidKey.java +++ b/src/main/java/io/appium/java_client/android/nativekey/AndroidKey.java @@ -1021,7 +1021,7 @@ public enum AndroidKey { * Key code constant: Media Top Menu key. * Goes to the top of media menu. */ - _MEDIA_TOP_MENU(226), + MEDIA_TOP_MENU(226), /** * Key code constant: '11' key. */ @@ -1178,7 +1178,7 @@ public enum AndroidKey { * Goes to the context menu of media contents. Corresponds to Media Context-sensitive * Menu (0x11) of CEC User Control Code. */ - _TV_MEDIA_CONTEXT_MENU(257), + TV_MEDIA_CONTEXT_MENU(257), /** * Key code constant: Timer programming key. * Goes to the timer recording menu. Corresponds to Timer Programming (0x54) of From f5470d9cf355e56023f4a14dba4e80af5ea840fc Mon Sep 17 00:00:00 2001 From: Srinivasan Sekar Date: Tue, 8 Oct 2019 16:49:08 +0100 Subject: [PATCH 013/690] Revert "Upgraded Selenium version to alpha 2. (#1210)" This reverts commit 7239a9d44cd088b6c457c93ac8a90a4cf797dd17. --- gradle.properties | 2 +- .../appium/java_client/remote/AppiumCommandExecutor.java | 2 +- .../java_client/remote/AppiumW3CHttpCommandCodec.java | 2 +- .../java_client/android/OpenNotificationsTest.java | 3 +-- .../io/appium/java_client/android/UIAutomator2Test.java | 9 ++++----- .../element/generation/ios/IOSElementGenerationTest.java | 5 ++--- .../java/io/appium/java_client/ios/IOSAlertTest.java | 3 +-- .../java/io/appium/java_client/ios/IOSDriverTest.java | 9 ++++----- .../java/io/appium/java_client/ios/IOSElementTest.java | 3 +-- .../java_client/ios/IOSNativeWebTapSettingTest.java | 7 +++---- .../java/io/appium/java_client/ios/IOSTouchTest.java | 4 ++-- .../java/io/appium/java_client/ios/IOSWebViewTest.java | 7 ++----- .../java_client/pagefactory_tests/XCUITModeTest.java | 3 +-- 13 files changed, 24 insertions(+), 35 deletions(-) diff --git a/gradle.properties b/gradle.properties index 63b13d41e..9bd535700 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,4 +7,4 @@ signing.secretKeyRingFile=PathToYourKeyRingFile ossrhUsername=your-jira-id ossrhPassword=your-jira-password -selenium.version=4.0.0-alpha-2 \ No newline at end of file +selenium.version=3.141.59 diff --git a/src/main/java/io/appium/java_client/remote/AppiumCommandExecutor.java b/src/main/java/io/appium/java_client/remote/AppiumCommandExecutor.java index 707680b4f..3f094ff53 100644 --- a/src/main/java/io/appium/java_client/remote/AppiumCommandExecutor.java +++ b/src/main/java/io/appium/java_client/remote/AppiumCommandExecutor.java @@ -44,10 +44,10 @@ import org.openqa.selenium.remote.ProtocolHandshake; import org.openqa.selenium.remote.Response; import org.openqa.selenium.remote.ResponseCodec; -import org.openqa.selenium.remote.codec.w3c.W3CHttpCommandCodec; import org.openqa.selenium.remote.http.HttpClient; import org.openqa.selenium.remote.http.HttpRequest; import org.openqa.selenium.remote.http.HttpResponse; +import org.openqa.selenium.remote.http.W3CHttpCommandCodec; import org.openqa.selenium.remote.service.DriverService; import java.io.BufferedInputStream; diff --git a/src/main/java/io/appium/java_client/remote/AppiumW3CHttpCommandCodec.java b/src/main/java/io/appium/java_client/remote/AppiumW3CHttpCommandCodec.java index 0fe0ace05..aec7ebd75 100644 --- a/src/main/java/io/appium/java_client/remote/AppiumW3CHttpCommandCodec.java +++ b/src/main/java/io/appium/java_client/remote/AppiumW3CHttpCommandCodec.java @@ -32,7 +32,7 @@ import org.openqa.selenium.interactions.KeyInput; import org.openqa.selenium.interactions.Sequence; -import org.openqa.selenium.remote.codec.w3c.W3CHttpCommandCodec; +import org.openqa.selenium.remote.http.W3CHttpCommandCodec; import java.util.Collection; import java.util.Map; diff --git a/src/test/java/io/appium/java_client/android/OpenNotificationsTest.java b/src/test/java/io/appium/java_client/android/OpenNotificationsTest.java index d6af69d05..7806ecc14 100644 --- a/src/test/java/io/appium/java_client/android/OpenNotificationsTest.java +++ b/src/test/java/io/appium/java_client/android/OpenNotificationsTest.java @@ -1,6 +1,5 @@ package io.appium.java_client.android; -import static java.time.Duration.ofSeconds; import static org.junit.Assert.assertNotEquals; import static org.openqa.selenium.By.id; @@ -15,7 +14,7 @@ public class OpenNotificationsTest extends BaseAndroidTest { public void openNotification() { driver.closeApp(); driver.openNotifications(); - WebDriverWait wait = new WebDriverWait(driver, ofSeconds(20)); + WebDriverWait wait = new WebDriverWait(driver, 20); assertNotEquals(0, wait.until(input -> { List result = input .findElements(id("com.android.systemui:id/settings_button")); diff --git a/src/test/java/io/appium/java_client/android/UIAutomator2Test.java b/src/test/java/io/appium/java_client/android/UIAutomator2Test.java index bca878dda..19df3618a 100644 --- a/src/test/java/io/appium/java_client/android/UIAutomator2Test.java +++ b/src/test/java/io/appium/java_client/android/UIAutomator2Test.java @@ -1,6 +1,5 @@ package io.appium.java_client.android; -import static java.time.Duration.ofSeconds; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -24,7 +23,7 @@ public void afterMethod() { @Test public void testLandscapeRightRotation() { - new WebDriverWait(driver, ofSeconds(20)).until(ExpectedConditions + new WebDriverWait(driver, 20).until(ExpectedConditions .elementToBeClickable(driver.findElementById("android:id/content") .findElement(MobileBy.AccessibilityId("Graphics")))); DeviceRotation landscapeRightRotation = new DeviceRotation(0, 0, 90); @@ -34,7 +33,7 @@ public void testLandscapeRightRotation() { @Test public void testLandscapeLeftRotation() { - new WebDriverWait(driver, ofSeconds(20)).until(ExpectedConditions + new WebDriverWait(driver, 20).until(ExpectedConditions .elementToBeClickable(driver.findElementById("android:id/content") .findElement(MobileBy.AccessibilityId("Graphics")))); DeviceRotation landscapeLeftRotation = new DeviceRotation(0, 0, 270); @@ -44,7 +43,7 @@ public void testLandscapeLeftRotation() { @Test public void testPortraitUpsideDown() { - new WebDriverWait(driver, ofSeconds(20)).until(ExpectedConditions + new WebDriverWait(driver, 20).until(ExpectedConditions .elementToBeClickable(driver.findElementById("android:id/content") .findElement(MobileBy.AccessibilityId("Graphics")))); DeviceRotation landscapeRightRotation = new DeviceRotation(0, 0, 180); @@ -57,7 +56,7 @@ public void testPortraitUpsideDown() { */ @Ignore public void testToastMSGIsDisplayed() { - final WebDriverWait wait = new WebDriverWait(driver, ofSeconds(30)); + final WebDriverWait wait = new WebDriverWait(driver, 30); Activity activity = new Activity("io.appium.android.apis", ".view.PopupMenu1"); driver.startActivity(activity); diff --git a/src/test/java/io/appium/java_client/appium/element/generation/ios/IOSElementGenerationTest.java b/src/test/java/io/appium/java_client/appium/element/generation/ios/IOSElementGenerationTest.java index 7ed8832e5..0b7572be3 100644 --- a/src/test/java/io/appium/java_client/appium/element/generation/ios/IOSElementGenerationTest.java +++ b/src/test/java/io/appium/java_client/appium/element/generation/ios/IOSElementGenerationTest.java @@ -1,7 +1,6 @@ package io.appium.java_client.appium.element.generation.ios; import static io.appium.java_client.MobileBy.AccessibilityId; -import static java.time.Duration.ofSeconds; import static org.junit.Assert.assertTrue; import static org.openqa.selenium.By.id; import static org.openqa.selenium.By.name; @@ -85,11 +84,11 @@ public void whenIOSHybridAppIsLaunched() { Capabilities caps = commonAppCapabilitiesSupplier.get(); return caps.merge(appFileSupplierFunction.apply(webViewApp).get()); }, (by, aClass) -> { - new WebDriverWait(driver, ofSeconds(30)) + new WebDriverWait(driver, 30) .until(ExpectedConditions.presenceOfElementLocated(id("login"))) .click(); driver.findElementByAccessibilityId("webView").click(); - new WebDriverWait(driver, ofSeconds(30)) + new WebDriverWait(driver, 30) .until(ExpectedConditions .presenceOfElementLocated(AccessibilityId("Webview"))); try { diff --git a/src/test/java/io/appium/java_client/ios/IOSAlertTest.java b/src/test/java/io/appium/java_client/ios/IOSAlertTest.java index 7c46a3c4d..06df51bd7 100644 --- a/src/test/java/io/appium/java_client/ios/IOSAlertTest.java +++ b/src/test/java/io/appium/java_client/ios/IOSAlertTest.java @@ -16,7 +16,6 @@ package io.appium.java_client.ios; -import static java.time.Duration.ofSeconds; import static junit.framework.TestCase.assertFalse; import static org.junit.Assert.assertTrue; import static org.openqa.selenium.support.ui.ExpectedConditions.alertIsPresent; @@ -33,7 +32,7 @@ @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class IOSAlertTest extends AppIOSTest { - private WebDriverWait waiting = new WebDriverWait(driver, ofSeconds(10000)); + private WebDriverWait waiting = new WebDriverWait(driver, 10000); private static final String iOSAutomationText = "show alert"; @Test public void acceptAlertTest() { diff --git a/src/test/java/io/appium/java_client/ios/IOSDriverTest.java b/src/test/java/io/appium/java_client/ios/IOSDriverTest.java index 69056af48..995ac4c58 100644 --- a/src/test/java/io/appium/java_client/ios/IOSDriverTest.java +++ b/src/test/java/io/appium/java_client/ios/IOSDriverTest.java @@ -16,7 +16,6 @@ package io.appium.java_client.ios; -import static java.time.Duration.ofSeconds; import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.greaterThan; @@ -57,7 +56,7 @@ public void getDeviceTimeTest() { } @Test public void hideKeyboardWithParametersTest() { - new WebDriverWait(driver, ofSeconds(30)) + new WebDriverWait(driver, 30) .until(ExpectedConditions.presenceOfElementLocated(By.id("IntegerA"))) .click(); driver.hideKeyboard(HideKeyboardStrategy.PRESS_KEY, "Done"); @@ -103,7 +102,7 @@ public void getDeviceTimeTest() { @Test public void putAppIntoBackgroundAndRestoreTest() { final long msStarted = System.currentTimeMillis(); - driver.runAppInBackground(ofSeconds(4)); + driver.runAppInBackground(Duration.ofSeconds(4)); assertThat(System.currentTimeMillis() - msStarted, greaterThan(3000L)); } @@ -120,7 +119,7 @@ public void getDeviceTimeTest() { } assertThat(driver.queryAppState(BUNDLE_ID), equalTo(ApplicationState.RUNNING_IN_FOREGROUND)); Thread.sleep(500); - driver.runAppInBackground(ofSeconds(-1)); + driver.runAppInBackground(Duration.ofSeconds(-1)); assertThat(driver.queryAppState(BUNDLE_ID), lessThan(ApplicationState.RUNNING_IN_FOREGROUND)); Thread.sleep(500); driver.activateApp(BUNDLE_ID); @@ -129,7 +128,7 @@ public void getDeviceTimeTest() { @Test public void putAIntoBackgroundWithoutRestoreTest() { assertThat(driver.findElementsById("IntegerA"), is(not(empty()))); - driver.runAppInBackground(ofSeconds(-1)); + driver.runAppInBackground(Duration.ofSeconds(-1)); assertThat(driver.findElementsById("IntegerA"), is(empty())); driver.launchApp(); } diff --git a/src/test/java/io/appium/java_client/ios/IOSElementTest.java b/src/test/java/io/appium/java_client/ios/IOSElementTest.java index 18bbf0d69..4389d1888 100644 --- a/src/test/java/io/appium/java_client/ios/IOSElementTest.java +++ b/src/test/java/io/appium/java_client/ios/IOSElementTest.java @@ -1,6 +1,5 @@ package io.appium.java_client.ios; -import static java.time.Duration.ofSeconds; import static org.hamcrest.core.Is.is; import static org.hamcrest.core.IsNot.not; import static org.junit.Assert.assertEquals; @@ -26,7 +25,7 @@ public void findByAccessibilityIdTest() { @Ignore @Test public void setValueTest() { - WebDriverWait wait = new WebDriverWait(driver, ofSeconds(20)); + WebDriverWait wait = new WebDriverWait(driver, 20); IOSElement slider = wait.until( driver1 -> driver1.findElement(By.className("XCUIElementTypeSlider"))); diff --git a/src/test/java/io/appium/java_client/ios/IOSNativeWebTapSettingTest.java b/src/test/java/io/appium/java_client/ios/IOSNativeWebTapSettingTest.java index 25746f91b..de8bcbb36 100644 --- a/src/test/java/io/appium/java_client/ios/IOSNativeWebTapSettingTest.java +++ b/src/test/java/io/appium/java_client/ios/IOSNativeWebTapSettingTest.java @@ -1,6 +1,5 @@ package io.appium.java_client.ios; -import static java.time.Duration.ofSeconds; import static org.junit.Assert.assertTrue; import org.junit.Test; @@ -18,17 +17,17 @@ public class IOSNativeWebTapSettingTest extends BaseSafariTest { driver.nativeWebTap(true); WebElement el = driver.findElementById("i am a link"); el.click(); - assertTrue(new WebDriverWait(driver, ofSeconds(30)) + assertTrue(new WebDriverWait(driver, 30) .until(ExpectedConditions.titleIs("I am another page title - Sauce Labs"))); driver.navigate().back(); // now do a click with it turned off and assert the same behavior - assertTrue(new WebDriverWait(driver, ofSeconds(30)) + assertTrue(new WebDriverWait(driver, 30) .until(ExpectedConditions.titleIs("I am a page title - Sauce Labs"))); driver.nativeWebTap(false); el = driver.findElementById("i am a link"); el.click(); - assertTrue(new WebDriverWait(driver, ofSeconds(30)) + assertTrue(new WebDriverWait(driver, 30) .until(ExpectedConditions.titleIs("I am another page title - Sauce Labs"))); } } diff --git a/src/test/java/io/appium/java_client/ios/IOSTouchTest.java b/src/test/java/io/appium/java_client/ios/IOSTouchTest.java index 8b6d34b04..ea2f83d9d 100644 --- a/src/test/java/io/appium/java_client/ios/IOSTouchTest.java +++ b/src/test/java/io/appium/java_client/ios/IOSTouchTest.java @@ -58,7 +58,7 @@ public void touchWithPressureTest() { } @Test public void swipeTest() { - WebDriverWait webDriverWait = new WebDriverWait(driver, ofSeconds(30)); + WebDriverWait webDriverWait = new WebDriverWait(driver, 30); IOSElement slider = webDriverWait.until(driver1 -> driver.findElementByClassName("XCUIElementTypeSlider")); Dimension size = slider.getSize(); @@ -82,7 +82,7 @@ public void touchWithPressureTest() { new MultiTouchAction(driver).add(tap1).add(tap2).perform(); - WebDriverWait waiting = new WebDriverWait(driver, ofSeconds(10000)); + WebDriverWait waiting = new WebDriverWait(driver, 10000); assertNotNull(waiting.until(alertIsPresent())); driver.switchTo().alert().accept(); } diff --git a/src/test/java/io/appium/java_client/ios/IOSWebViewTest.java b/src/test/java/io/appium/java_client/ios/IOSWebViewTest.java index d12d5aa16..7c8f380c3 100644 --- a/src/test/java/io/appium/java_client/ios/IOSWebViewTest.java +++ b/src/test/java/io/appium/java_client/ios/IOSWebViewTest.java @@ -1,6 +1,5 @@ package io.appium.java_client.ios; -import static java.time.Duration.ofSeconds; import static org.junit.Assert.assertTrue; import io.appium.java_client.MobileBy; @@ -10,16 +9,14 @@ import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; -import java.time.Duration; - public class IOSWebViewTest extends BaseIOSWebViewTest { @Test public void webViewPageTestCase() throws InterruptedException { - new WebDriverWait(driver, ofSeconds(30)) + new WebDriverWait(driver, 30) .until(ExpectedConditions.presenceOfElementLocated(By.id("login"))) .click(); driver.findElementByAccessibilityId("webView").click(); - new WebDriverWait(driver, ofSeconds(30)) + new WebDriverWait(driver, 30) .until(ExpectedConditions.presenceOfElementLocated(MobileBy.AccessibilityId("Webview"))); findAndSwitchToWebView(); WebElement el = driver.findElementByPartialLinkText("login"); diff --git a/src/test/java/io/appium/java_client/pagefactory_tests/XCUITModeTest.java b/src/test/java/io/appium/java_client/pagefactory_tests/XCUITModeTest.java index cd683709b..c54bf9129 100644 --- a/src/test/java/io/appium/java_client/pagefactory_tests/XCUITModeTest.java +++ b/src/test/java/io/appium/java_client/pagefactory_tests/XCUITModeTest.java @@ -19,7 +19,6 @@ import static io.appium.java_client.pagefactory.LocatorGroupStrategy.ALL_POSSIBLE; import static io.appium.java_client.pagefactory.LocatorGroupStrategy.CHAIN; -import static java.time.Duration.ofSeconds; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.greaterThan; @@ -48,7 +47,7 @@ public class XCUITModeTest extends AppIOSTest { private boolean populated = false; - private WebDriverWait waiting = new WebDriverWait(driver, ofSeconds(10000)); + private WebDriverWait waiting = new WebDriverWait(driver, 10000); @HowToUseLocators(iOSXCUITAutomation = ALL_POSSIBLE) @iOSXCUITFindBy(iOSNsPredicate = "label contains 'Compute'") From 75135e2d521905f64c3275ba874ecbd9904afa19 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Fri, 18 Oct 2019 21:48:34 +0200 Subject: [PATCH 014/690] refactor: Update the implementation of Appium executables detection (#1256) --- .../local/AppiumDriverLocalService.java | 60 ++-- .../service/local/AppiumServiceBuilder.java | 281 +++++++----------- .../local/InvalidServerInstanceException.java | 8 +- .../java_client/service/local/Scripts.java | 80 ----- src/main/resources/scripts/getExe.js | 1 - .../scripts/get_path_to_default_node.sh | 4 - .../java/io/appium/java_client/TestUtils.java | 16 + .../io/appium/java_client/ios/AppIOSTest.java | 4 +- .../appium/java_client/ios/BaseIOSTest.java | 12 +- .../java_client/ios/BaseIOSWebViewTest.java | 5 +- .../java_client/ios/BaseSafariTest.java | 5 +- .../java_client/ios/UICatalogIOSTest.java | 5 +- .../service/local/ServerBuilderTest.java | 103 ++++--- 13 files changed, 230 insertions(+), 354 deletions(-) delete mode 100644 src/main/java/io/appium/java_client/service/local/Scripts.java delete mode 100644 src/main/resources/scripts/getExe.js delete mode 100644 src/main/resources/scripts/get_path_to_default_node.sh create mode 100644 src/test/java/io/appium/java_client/TestUtils.java diff --git a/src/main/java/io/appium/java_client/service/local/AppiumDriverLocalService.java b/src/main/java/io/appium/java_client/service/local/AppiumDriverLocalService.java index a7fd502b2..c3f9e0389 100644 --- a/src/main/java/io/appium/java_client/service/local/AppiumDriverLocalService.java +++ b/src/main/java/io/appium/java_client/service/local/AppiumDriverLocalService.java @@ -17,6 +17,7 @@ package io.appium.java_client.service.local; import static com.google.common.base.Preconditions.checkNotNull; +import static io.appium.java_client.service.local.AppiumServiceBuilder.BROADCAST_IP_ADDRESS; import static org.slf4j.event.Level.DEBUG; import static org.slf4j.event.Level.INFO; @@ -67,8 +68,8 @@ public final class AppiumDriverLocalService extends DriverService { private CommandLine process = null; AppiumDriverLocalService(String ipAddress, File nodeJSExec, int nodeJSPort, - ImmutableList nodeJSArgs, ImmutableMap nodeJSEnvironment, - long startupTimeout, TimeUnit timeUnit) throws IOException { + ImmutableList nodeJSArgs, ImmutableMap nodeJSEnvironment, + long startupTimeout, TimeUnit timeUnit) throws IOException { super(nodeJSExec, nodeJSPort, nodeJSArgs, nodeJSEnvironment); this.nodeJSExec = nodeJSExec; this.nodeJSArgs = nodeJSArgs; @@ -91,11 +92,13 @@ public static AppiumDriverLocalService buildService(AppiumServiceBuilder builder * * @return The base URL for the managed appium server. */ - @Override public URL getUrl() { + @Override + public URL getUrl() { return url; } - @Override public boolean isRunning() { + @Override + public boolean isRunning() { lock.lock(); try { if (process == null) { @@ -121,15 +124,15 @@ public static AppiumDriverLocalService buildService(AppiumServiceBuilder builder } private void ping(long time, TimeUnit timeUnit) throws UrlChecker.TimeoutException, MalformedURLException { - URL status = new URL(url.toString() + "/status"); + // The operating system might block direct access to the universal broadcast IP address + URL status = new URL(url.toString().replace(BROADCAST_IP_ADDRESS, "127.0.0.1") + "/status"); new UrlChecker().waitUntilAvailable(time, timeUnit, status); } /** * Starts the defined appium server. * - * @throws AppiumServerHasNotBeenStartedLocallyException - * If an error occurs while spawning the child process. + * @throws AppiumServerHasNotBeenStartedLocallyException If an error occurs while spawning the child process. * @see #stop() */ public void start() throws AppiumServerHasNotBeenStartedLocallyException { @@ -141,7 +144,7 @@ public void start() throws AppiumServerHasNotBeenStartedLocallyException { try { process = new CommandLine(this.nodeJSExec.getCanonicalPath(), - nodeJSArgs.toArray(new String[] {})); + nodeJSArgs.toArray(new String[]{})); process.setEnvironmentVariables(nodeJSEnvironment); process.copyOutputTo(stream); process.executeAsync(); @@ -149,8 +152,8 @@ public void start() throws AppiumServerHasNotBeenStartedLocallyException { } catch (Throwable e) { destroyProcess(); String msgTxt = "The local appium server has not been started. " - + "The given Node.js executable: " + this.nodeJSExec.getAbsolutePath() - + " Arguments: " + nodeJSArgs.toString() + " " + "\n"; + + "The given Node.js executable: " + this.nodeJSExec.getAbsolutePath() + + " Arguments: " + nodeJSArgs.toString() + " " + "\n"; if (process != null) { String processStream = process.getStdOut(); if (!StringUtils.isBlank(processStream)) { @@ -171,7 +174,8 @@ public void start() throws AppiumServerHasNotBeenStartedLocallyException { * * @see #start() */ - @Override public void stop() { + @Override + public void stop() { lock.lock(); try { if (process != null) { @@ -192,8 +196,7 @@ private void destroyProcess() { /** * Logs as string. * - * @return String logs if the server has been run. - * null is returned otherwise. + * @return String logs if the server has been run. Null is returned otherwise. */ @Nullable public String getStdOut() { @@ -206,6 +209,7 @@ public String getStdOut() { /** * Adds other output stream which should accept server output data. + * * @param outputStream is an instance of {@link OutputStream} * that is ready to accept server output */ @@ -216,6 +220,7 @@ public void addOutPutStream(OutputStream outputStream) { /** * Adds other output streams which should accept server output data. + * * @param outputStreams is a list of additional {@link OutputStream} * that are ready to accept server output */ @@ -240,12 +245,12 @@ public boolean clearOutPutStreams() { * SLF4J loggers. This allow server output * data to be configured with your preferred logging frameworks (e.g. * java.util.logging, logback, log4j). - * + * *

NOTE1: You might want to call method {@link #clearOutPutStreams()} before * calling this method.
* NOTE2: it is required that {@code --log-timestamp} server flag is * {@code false}. - * + * *

By default log messages are: *