From e6b05fcadcea1e0603a965fa08fb5d43194b8441 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Thu, 28 Oct 2021 08:29:27 +0200 Subject: [PATCH 1/5] chore: Add the rest of XCUITest driver options --- .../android/options/UiAutomator2Options.java | 2 +- .../ios/options/XCUITestOptions.java | 18 ++++- .../other/SupportsCommandTimeoutsOption.java | 76 +++++++++++++++++++ .../other/SupportsLaunchWithIdbOption.java | 62 +++++++++++++++ ...SupportsResetOnSessionStartOnlyOption.java | 52 +++++++++++++ .../other/SupportsShowIosLogOption.java | 59 ++++++++++++++ .../other/SupportsUseJsonSourceOption.java | 60 +++++++++++++++ .../SupportsSkipLogCaptureOption.java | 10 +-- 8 files changed, 329 insertions(+), 10 deletions(-) create mode 100644 src/main/java/io/appium/java_client/ios/options/other/SupportsCommandTimeoutsOption.java create mode 100644 src/main/java/io/appium/java_client/ios/options/other/SupportsLaunchWithIdbOption.java create mode 100644 src/main/java/io/appium/java_client/ios/options/other/SupportsResetOnSessionStartOnlyOption.java create mode 100644 src/main/java/io/appium/java_client/ios/options/other/SupportsShowIosLogOption.java create mode 100644 src/main/java/io/appium/java_client/ios/options/other/SupportsUseJsonSourceOption.java rename src/main/java/io/appium/java_client/{android/options/other => remote/options}/SupportsSkipLogCaptureOption.java (82%) diff --git a/src/main/java/io/appium/java_client/android/options/UiAutomator2Options.java b/src/main/java/io/appium/java_client/android/options/UiAutomator2Options.java index ee9ae2755..6520cd672 100644 --- a/src/main/java/io/appium/java_client/android/options/UiAutomator2Options.java +++ b/src/main/java/io/appium/java_client/android/options/UiAutomator2Options.java @@ -78,7 +78,7 @@ import io.appium.java_client.android.options.mjpeg.SupportsMjpegScreenshotUrlOption; import io.appium.java_client.android.options.mjpeg.SupportsMjpegServerPortOption; import io.appium.java_client.android.options.other.SupportsDisableSuppressAccessibilityServiceOption; -import io.appium.java_client.android.options.other.SupportsSkipLogCaptureOption; +import io.appium.java_client.remote.options.SupportsSkipLogCaptureOption; import io.appium.java_client.android.options.other.SupportsUserProfileOption; import io.appium.java_client.android.options.server.SupportsDisableWindowAnimationOption; import io.appium.java_client.android.options.server.SupportsSkipDeviceInitializationOption; diff --git a/src/main/java/io/appium/java_client/ios/options/XCUITestOptions.java b/src/main/java/io/appium/java_client/ios/options/XCUITestOptions.java index eab916b61..e558d602a 100644 --- a/src/main/java/io/appium/java_client/ios/options/XCUITestOptions.java +++ b/src/main/java/io/appium/java_client/ios/options/XCUITestOptions.java @@ -22,6 +22,11 @@ import io.appium.java_client.ios.options.app.SupportsLocalizableStringsDirOption; import io.appium.java_client.ios.options.general.SupportsIncludeDeviceCapsToSessionInfoOption; import io.appium.java_client.ios.options.general.SupportsResetLocationServiceOption; +import io.appium.java_client.ios.options.other.SupportsCommandTimeoutsOption; +import io.appium.java_client.ios.options.other.SupportsLaunchWithIdbOption; +import io.appium.java_client.ios.options.other.SupportsResetOnSessionStartOnlyOption; +import io.appium.java_client.ios.options.other.SupportsShowIosLogOption; +import io.appium.java_client.ios.options.other.SupportsUseJsonSourceOption; import io.appium.java_client.ios.options.simulator.SupportsCalendarAccessAuthorizedOption; import io.appium.java_client.ios.options.simulator.SupportsCalendarFormatOption; import io.appium.java_client.ios.options.simulator.SupportsConnectHardwareKeyboardOption; @@ -106,6 +111,7 @@ import io.appium.java_client.remote.options.SupportsLocaleOption; import io.appium.java_client.remote.options.SupportsOrientationOption; import io.appium.java_client.remote.options.SupportsOtherAppsOption; +import io.appium.java_client.remote.options.SupportsSkipLogCaptureOption; import io.appium.java_client.remote.options.SupportsUdidOption; import org.openqa.selenium.Capabilities; @@ -205,9 +211,15 @@ public class XCUITestOptions extends BaseOptions implements SupportsWebkitResponseTimeoutOption, SupportsEnableAsyncExecuteFromHttpsOption, SupportsFullContextListOption, - // TODO: Other options: https://github.com/appium/appium-xcuitest-driver#other - SupportsClearSystemFilesOption, - SupportsEnablePerformanceLoggingOption { + SupportsEnablePerformanceLoggingOption, + // Other options: https://github.com/appium/appium-xcuitest-driver#other + SupportsResetOnSessionStartOnlyOption, + SupportsCommandTimeoutsOption, + SupportsUseJsonSourceOption, + SupportsSkipLogCaptureOption, + SupportsLaunchWithIdbOption, + SupportsShowIosLogOption, + SupportsClearSystemFilesOption { public XCUITestOptions() { setCommonOptions(); diff --git a/src/main/java/io/appium/java_client/ios/options/other/SupportsCommandTimeoutsOption.java b/src/main/java/io/appium/java_client/ios/options/other/SupportsCommandTimeoutsOption.java new file mode 100644 index 000000000..d9b4890da --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/other/SupportsCommandTimeoutsOption.java @@ -0,0 +1,76 @@ +/* + * 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.ios.options.other; + +import com.google.gson.JsonObject; +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.util.Optional; + +public interface SupportsCommandTimeoutsOption> extends + Capabilities, CanSetCapability { + String COMMAND_TIMEOUTS_OPTION = "commandTimeouts"; + + /** + * Custom timeout(s) in milliseconds for WDA backend commands execution. + * This might be useful if WDA backend freezes unexpectedly or requires too + * much time to fail and blocks automated test execution. The value is expected + * to be of type string and can either contain max milliseconds to wait for + * each WDA command to be executed before terminating the session forcefully + * or a valid JSON string, where keys are internal Appium command names (you + * can find these in logs, look for "Executing command 'command_name'" records) + * and values are timeouts in milliseconds. You can also set the 'default' key + * to assign the timeout for all other commands not explicitly enumerated as + * JSON keys. + * + * @param timeouts E.g. '{"findElement": 40000, "findElements": 40000}'. + * @return self instance for chaining. + */ + default T setCommandTimeouts(JsonObject timeouts) { + return amend(COMMAND_TIMEOUTS_OPTION, timeouts.toString()); + } + + /** + * Custom timeout(s) in milliseconds for WDA backend commands execution. + * This might be useful if WDA backend freezes unexpectedly or requires too + * much time to fail and blocks automated test execution. The value is expected + * to be of type string and can either contain max milliseconds to wait for + * each WDA command to be executed before terminating the session forcefully + * or a valid JSON string, where keys are internal Appium command names (you + * can find these in logs, look for "Executing command 'command_name'" records) + * and values are timeouts in milliseconds. You can also set the 'default' key + * to assign the timeout for all other commands not explicitly enumerated as + * JSON keys. + * + * @param timeouts E.g. '120000', '{"findElement": 40000, "findElements": 40000}'. + * @return self instance for chaining. + */ + default T setCommandTimeouts(String timeouts) { + return amend(COMMAND_TIMEOUTS_OPTION, timeouts); + } + + /** + * Get custom timeout(s) in milliseconds for WDA backend commands execution. + * + * @return Command timeouts. + */ + default Optional setCommandTimeouts() { + return Optional.ofNullable((String) getCapability(COMMAND_TIMEOUTS_OPTION)); + } +} diff --git a/src/main/java/io/appium/java_client/ios/options/other/SupportsLaunchWithIdbOption.java b/src/main/java/io/appium/java_client/ios/options/other/SupportsLaunchWithIdbOption.java new file mode 100644 index 000000000..e4f910072 --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/other/SupportsLaunchWithIdbOption.java @@ -0,0 +1,62 @@ +/* + * 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.ios.options.other; + +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.util.Optional; + +import static io.appium.java_client.internal.CapabilityHelpers.toSafeBoolean; + +public interface SupportsLaunchWithIdbOption> extends + Capabilities, CanSetCapability { + String LAUNCH_WITH_IDB_OPTION = "launchWithIDB"; + + /** + * Enforces launching of WebDriverAgentRunner with idb instead of xcodebuild. + * + * @return self instance for chaining. + */ + default T launchWithIdb() { + return amend(LAUNCH_WITH_IDB_OPTION, true); + } + + /** + * Launch WebDriverAgentRunner with idb instead of xcodebuild. This could save + * a significant amount of time by skipping the xcodebuild process, although the + * idb might not be very reliable, especially with fresh Xcode SDKs. Check + * the idb repository for more details on possible compatibility issues. + * Defaults to false. + * + * @param value Whether to launch WebDriverAgentRunner with idb instead of xcodebuild. + * @return self instance for chaining. + */ + default T setLaunchWithIdb(boolean value) { + return amend(LAUNCH_WITH_IDB_OPTION, value); + } + + /** + * Get whether to launch WebDriverAgentRunner with idb instead of xcodebuild + * + * @return True or false. + */ + default Optional doesLaunchWithIdb() { + return Optional.ofNullable(toSafeBoolean(getCapability(LAUNCH_WITH_IDB_OPTION))); + } +} diff --git a/src/main/java/io/appium/java_client/ios/options/other/SupportsResetOnSessionStartOnlyOption.java b/src/main/java/io/appium/java_client/ios/options/other/SupportsResetOnSessionStartOnlyOption.java new file mode 100644 index 000000000..65f29c837 --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/other/SupportsResetOnSessionStartOnlyOption.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.ios.options.other; + +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.util.Optional; + +import static io.appium.java_client.internal.CapabilityHelpers.toSafeBoolean; + +public interface SupportsResetOnSessionStartOnlyOption> extends + Capabilities, CanSetCapability { + String RESET_ON_SESSION_START_ONLY_OPTION = "resetOnSessionStartOnly"; + + /** + * Whether to perform reset on test session finish (false) or not (true). + * Keeping this variable set to true and Simulator running (the default + * behaviour since version 1.6.4) may significantly shorten the duration of + * test session initialization. + * + * @param value Whether to perform reset on test session finish (false) or not (true).. + * @return self instance for chaining. + */ + default T setResetOnSessionStartOnly(boolean value) { + return amend(RESET_ON_SESSION_START_ONLY_OPTION, value); + } + + /** + * Get whether to perform reset on test session finish (false) or not (true). + * + * @return True or false. + */ + default Optional doesResetOnSessionStartOnly() { + return Optional.ofNullable(toSafeBoolean(getCapability(RESET_ON_SESSION_START_ONLY_OPTION))); + } +} diff --git a/src/main/java/io/appium/java_client/ios/options/other/SupportsShowIosLogOption.java b/src/main/java/io/appium/java_client/ios/options/other/SupportsShowIosLogOption.java new file mode 100644 index 000000000..ee0676d44 --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/other/SupportsShowIosLogOption.java @@ -0,0 +1,59 @@ +/* + * 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.ios.options.other; + +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.util.Optional; + +import static io.appium.java_client.internal.CapabilityHelpers.toSafeBoolean; + +public interface SupportsShowIosLogOption> extends + Capabilities, CanSetCapability { + String SHOW_IOS_LOG_OPTION = "showIOSLog"; + + /** + * Enforces showing any logs captured from a device in the appium logs. + * + * @return self instance for chaining. + */ + default T showIosLog() { + return amend(SHOW_IOS_LOG_OPTION, true); + } + + /** + * Whether to show any logs captured from a device in the appium logs. + * Default false. + * + * @param value Whether to show any logs captured from a device in the appium logs. + * @return self instance for chaining. + */ + default T setShowIosLog(boolean value) { + return amend(SHOW_IOS_LOG_OPTION, value); + } + + /** + * Get whether to show any logs captured from a device in the appium logs. + * + * @return True or false. + */ + default Optional doesShowIosLog() { + return Optional.ofNullable(toSafeBoolean(getCapability(SHOW_IOS_LOG_OPTION))); + } +} diff --git a/src/main/java/io/appium/java_client/ios/options/other/SupportsUseJsonSourceOption.java b/src/main/java/io/appium/java_client/ios/options/other/SupportsUseJsonSourceOption.java new file mode 100644 index 000000000..dd88a9a34 --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/other/SupportsUseJsonSourceOption.java @@ -0,0 +1,60 @@ +/* + * 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.ios.options.other; + +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.util.Optional; + +import static io.appium.java_client.internal.CapabilityHelpers.toSafeBoolean; + +public interface SupportsUseJsonSourceOption> extends + Capabilities, CanSetCapability { + String USE_JSON_SOURCE_OPTION = "useJSONSource"; + + /** + * Enforces getting JSON source from WDA and transform it to XML on the Appium + * server side. + * + * @return self instance for chaining. + */ + default T useJSONSource() { + return amend(USE_JSON_SOURCE_OPTION, true); + } + + /** + * Get JSON source from WDA and transform it to XML on the Appium server side. + * Defaults to false. + * + * @param value Whether to get JSON source from WDA and transform it to XML. + * @return self instance for chaining. + */ + default T setUseJSONSource(boolean value) { + return amend(USE_JSON_SOURCE_OPTION, value); + } + + /** + * Get whether to get JSON source from WDA and transform it to XML. + * + * @return True or false. + */ + default Optional doesUseJSONSource() { + return Optional.ofNullable(toSafeBoolean(getCapability(USE_JSON_SOURCE_OPTION))); + } +} diff --git a/src/main/java/io/appium/java_client/android/options/other/SupportsSkipLogCaptureOption.java b/src/main/java/io/appium/java_client/remote/options/SupportsSkipLogCaptureOption.java similarity index 82% rename from src/main/java/io/appium/java_client/android/options/other/SupportsSkipLogCaptureOption.java rename to src/main/java/io/appium/java_client/remote/options/SupportsSkipLogCaptureOption.java index 79c48e2a2..8da26009c 100644 --- a/src/main/java/io/appium/java_client/android/options/other/SupportsSkipLogCaptureOption.java +++ b/src/main/java/io/appium/java_client/remote/options/SupportsSkipLogCaptureOption.java @@ -14,10 +14,8 @@ * limitations under the License. */ -package io.appium.java_client.android.options.other; +package io.appium.java_client.remote.options; -import io.appium.java_client.remote.options.BaseOptions; -import io.appium.java_client.remote.options.CanSetCapability; import org.openqa.selenium.Capabilities; import java.util.Optional; @@ -29,7 +27,7 @@ public interface SupportsSkipLogCaptureOption> extends String SKIP_LOG_CAPTURE_OPTION = "skipLogCapture"; /** - * Skips capturing logs such as logcat. + * Skips capturing system logs. * * @return self instance for chaining. */ @@ -38,7 +36,7 @@ default T skipLogCapture() { } /** - * Skips to start capturing logs such as logcat. It might improve network performance. + * Skips to start capturing system logs. It might improve network performance. * Log-related commands won't work if the capability is enabled. Defaults to false. * * @param value Set it to true in order to skip logcat capture. @@ -49,7 +47,7 @@ default T setSkipLogCapture(boolean value) { } /** - * Get whether to skip capturing logs such as logcat. + * Get whether to skip capturing system logs. * * @return True or false. */ From 67480a10472321c31aebaab887b3350c71bc3409 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Thu, 28 Oct 2021 09:09:45 +0200 Subject: [PATCH 2/5] Update tests --- .../other/SupportsCommandTimeoutsOption.java | 13 ++-- .../remote/options/BaseOptions.java | 1 + .../options/SupportsBrowserNameOption.java | 34 +++++++++ .../java_client/android/FingerPrintTest.java | 13 ++-- .../java_client/android/IntentTest.java | 11 ++- .../io/appium/java_client/ios/AppIOSTest.java | 26 +++---- .../java_client/ios/BaseIOSWebViewTest.java | 21 ++---- .../java_client/ios/BaseSafariTest.java | 20 ++--- .../MobileBrowserCompatibilityTest.java | 26 ++++--- .../service/local/ServerBuilderTest.java | 58 +++++++-------- .../service/local/StartingAppLocallyTest.java | 73 ++++++++----------- 11 files changed, 150 insertions(+), 146 deletions(-) create mode 100644 src/main/java/io/appium/java_client/remote/options/SupportsBrowserNameOption.java diff --git a/src/main/java/io/appium/java_client/ios/options/other/SupportsCommandTimeoutsOption.java b/src/main/java/io/appium/java_client/ios/options/other/SupportsCommandTimeoutsOption.java index d9b4890da..42935504b 100644 --- a/src/main/java/io/appium/java_client/ios/options/other/SupportsCommandTimeoutsOption.java +++ b/src/main/java/io/appium/java_client/ios/options/other/SupportsCommandTimeoutsOption.java @@ -21,6 +21,7 @@ import io.appium.java_client.remote.options.CanSetCapability; import org.openqa.selenium.Capabilities; +import java.time.Duration; import java.util.Optional; public interface SupportsCommandTimeoutsOption> extends @@ -58,11 +59,11 @@ default T setCommandTimeouts(JsonObject timeouts) { * to assign the timeout for all other commands not explicitly enumerated as * JSON keys. * - * @param timeouts E.g. '120000', '{"findElement": 40000, "findElements": 40000}'. + * @param timeout The timeout value for all commands. * @return self instance for chaining. */ - default T setCommandTimeouts(String timeouts) { - return amend(COMMAND_TIMEOUTS_OPTION, timeouts); + default T setCommandTimeouts(Duration timeout) { + return amend(COMMAND_TIMEOUTS_OPTION, String.valueOf(timeout.toMillis())); } /** @@ -70,7 +71,9 @@ default T setCommandTimeouts(String timeouts) { * * @return Command timeouts. */ - default Optional setCommandTimeouts() { - return Optional.ofNullable((String) getCapability(COMMAND_TIMEOUTS_OPTION)); + default Optional getCommandTimeouts() { + return Optional.ofNullable( + (String) getCapability(COMMAND_TIMEOUTS_OPTION) + ); } } diff --git a/src/main/java/io/appium/java_client/remote/options/BaseOptions.java b/src/main/java/io/appium/java_client/remote/options/BaseOptions.java index bb597d195..16fb34232 100644 --- a/src/main/java/io/appium/java_client/remote/options/BaseOptions.java +++ b/src/main/java/io/appium/java_client/remote/options/BaseOptions.java @@ -46,6 +46,7 @@ public class BaseOptions> extends MutableCapabilities i SupportsNoResetOption, SupportsFullResetOption, SupportsNewCommandTimeoutOption, + SupportsBrowserNameOption, SupportsPlatformVersionOption { private static final AcceptedW3CCapabilityKeys W3C_KEY_PATTERNS = new AcceptedW3CCapabilityKeys(); diff --git a/src/main/java/io/appium/java_client/remote/options/SupportsBrowserNameOption.java b/src/main/java/io/appium/java_client/remote/options/SupportsBrowserNameOption.java new file mode 100644 index 000000000..b0506feda --- /dev/null +++ b/src/main/java/io/appium/java_client/remote/options/SupportsBrowserNameOption.java @@ -0,0 +1,34 @@ +/* + * 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.remote.options; + +import org.openqa.selenium.Capabilities; + +public interface SupportsBrowserNameOption> extends + Capabilities, CanSetCapability { + String BROWSER_NAME_OPTION = "browserName"; + + /** + * Set the browser name to use. + * + * @param browserName One of supported browser names. + * @return self instance for chaining. + */ + default T withBrowserName(String browserName) { + return amend(BROWSER_NAME_OPTION, browserName); + } +} diff --git a/src/test/java/io/appium/java_client/android/FingerPrintTest.java b/src/test/java/io/appium/java_client/android/FingerPrintTest.java index 9b296adf3..42d696b58 100644 --- a/src/test/java/io/appium/java_client/android/FingerPrintTest.java +++ b/src/test/java/io/appium/java_client/android/FingerPrintTest.java @@ -18,7 +18,7 @@ import static io.appium.java_client.AppiumBy.androidUIAutomator; -import io.appium.java_client.remote.MobileCapabilityType; +import io.appium.java_client.android.options.UiAutomator2Options; import io.appium.java_client.service.local.AppiumDriverLocalService; import org.junit.After; import org.junit.AfterClass; @@ -29,7 +29,6 @@ import org.openqa.selenium.By; import org.openqa.selenium.NoSuchElementException; import org.openqa.selenium.WebElement; -import org.openqa.selenium.remote.DesiredCapabilities; import java.time.Duration; @@ -38,11 +37,11 @@ public class FingerPrintTest { private static AndroidDriver driver; private static void initDriver() { - DesiredCapabilities capabilities = new DesiredCapabilities(); - capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "Android Emulator"); - capabilities.setCapability("appPackage", "com.android.settings"); - capabilities.setCapability("appActivity", "Settings"); - driver = new AndroidDriver(service.getUrl(), capabilities); + UiAutomator2Options options = new UiAutomator2Options() + .setDeviceName("Android Emulator") + .setAppPackage("com.android.settings") + .setAppActivity("Settings"); + driver = new AndroidDriver(service.getUrl(), options); driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(15)); } diff --git a/src/test/java/io/appium/java_client/android/IntentTest.java b/src/test/java/io/appium/java_client/android/IntentTest.java index 441af2a4e..ea10811e6 100644 --- a/src/test/java/io/appium/java_client/android/IntentTest.java +++ b/src/test/java/io/appium/java_client/android/IntentTest.java @@ -4,13 +4,12 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import io.appium.java_client.remote.MobileCapabilityType; +import io.appium.java_client.android.options.UiAutomator2Options; import io.appium.java_client.service.local.AppiumDriverLocalService; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.openqa.selenium.By; -import org.openqa.selenium.remote.DesiredCapabilities; import java.util.function.Predicate; @@ -29,10 +28,10 @@ public class IntentTest { throw new RuntimeException("An appium server node is not started!"); } - DesiredCapabilities capabilities = new DesiredCapabilities(); - capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "Android Emulator"); - capabilities.setCapability(MobileCapabilityType.APP, intentExampleApk().toAbsolutePath().toString()); - driver = new AndroidDriver(service.getUrl(), capabilities); + UiAutomator2Options options = new UiAutomator2Options() + .setDeviceName("Android Emulator") + .setApp(intentExampleApk().toAbsolutePath().toString()); + driver = new AndroidDriver(service.getUrl(), options); } /** diff --git a/src/test/java/io/appium/java_client/ios/AppIOSTest.java b/src/test/java/io/appium/java_client/ios/AppIOSTest.java index 26551d91b..5aad73dfe 100644 --- a/src/test/java/io/appium/java_client/ios/AppIOSTest.java +++ b/src/test/java/io/appium/java_client/ios/AppIOSTest.java @@ -1,14 +1,12 @@ package io.appium.java_client.ios; -import io.appium.java_client.remote.AutomationName; -import io.appium.java_client.remote.IOSMobileCapabilityType; -import io.appium.java_client.remote.MobileCapabilityType; +import io.appium.java_client.ios.options.XCUITestOptions; import io.appium.java_client.service.local.AppiumServerHasNotBeenStartedLocallyException; import org.junit.BeforeClass; import org.openqa.selenium.SessionNotCreatedException; -import org.openqa.selenium.remote.DesiredCapabilities; import java.net.URL; +import java.time.Duration; import static io.appium.java_client.TestResources.testAppZip; @@ -24,20 +22,16 @@ public static void beforeClass() throws Exception { throw new AppiumServerHasNotBeenStartedLocallyException("An appium server node is not started!"); } - DesiredCapabilities capabilities = new DesiredCapabilities(); - capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, PLATFORM_VERSION); - capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, DEVICE_NAME); - capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, AutomationName.IOS_XCUI_TEST); - capabilities.setCapability(IOSMobileCapabilityType.WDA_LAUNCH_TIMEOUT, - WDA_LAUNCH_TIMEOUT.toMillis()); - //sometimes environment has performance problems - capabilities.setCapability("commandTimeouts", "240000"); - capabilities.setCapability(MobileCapabilityType.APP, testAppZip().toAbsolutePath().toString()); + XCUITestOptions options = new XCUITestOptions() + .setDeviceName(DEVICE_NAME) + .setCommandTimeouts(Duration.ofSeconds(240)) + .setApp(testAppZip().toAbsolutePath().toString()) + .setWdaLaunchTimeout(WDA_LAUNCH_TIMEOUT); try { - driver = new IOSDriver(new URL("http://" + ip + ":" + PORT + "/wd/hub"), capabilities); + driver = new IOSDriver(new URL("http://" + ip + ":" + PORT + "/wd/hub"), options); } catch (SessionNotCreatedException e) { - capabilities.setCapability("useNewWDA", true); - driver = new IOSDriver(new URL("http://" + ip + ":" + PORT + "/wd/hub"), capabilities); + options.useNewWDA(); + driver = new IOSDriver(new URL("http://" + ip + ":" + PORT + "/wd/hub"), options); } } } \ No newline at end of file diff --git a/src/test/java/io/appium/java_client/ios/BaseIOSWebViewTest.java b/src/test/java/io/appium/java_client/ios/BaseIOSWebViewTest.java index 999719551..74b1c8f62 100644 --- a/src/test/java/io/appium/java_client/ios/BaseIOSWebViewTest.java +++ b/src/test/java/io/appium/java_client/ios/BaseIOSWebViewTest.java @@ -16,13 +16,10 @@ package io.appium.java_client.ios; -import io.appium.java_client.remote.AutomationName; -import io.appium.java_client.remote.IOSMobileCapabilityType; -import io.appium.java_client.remote.MobileCapabilityType; +import io.appium.java_client.ios.options.XCUITestOptions; import io.appium.java_client.service.local.AppiumServerHasNotBeenStartedLocallyException; import org.junit.BeforeClass; import org.openqa.selenium.SessionNotCreatedException; -import org.openqa.selenium.remote.DesiredCapabilities; import java.io.IOException; import java.net.MalformedURLException; @@ -44,16 +41,14 @@ public static void beforeClass() throws IOException { throw new AppiumServerHasNotBeenStartedLocallyException("An appium server node is not started!"); } - final DesiredCapabilities capabilities = new DesiredCapabilities(); - capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, PLATFORM_VERSION); - capabilities.setCapability(IOSMobileCapabilityType.WDA_LAUNCH_TIMEOUT, WDA_LAUNCH_TIMEOUT.toMillis()); - capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, DEVICE_NAME); - capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, AutomationName.IOS_XCUI_TEST); - capabilities.setCapability("commandTimeouts", "240000"); - capabilities.setCapability(MobileCapabilityType.APP, vodQaAppZip().toAbsolutePath().toString()); + XCUITestOptions options = new XCUITestOptions() + .setDeviceName(DEVICE_NAME) + .setWdaLaunchTimeout(WDA_LAUNCH_TIMEOUT) + .setCommandTimeouts(Duration.ofSeconds(240)) + .setApp(vodQaAppZip().toAbsolutePath().toString()); Supplier createDriver = () -> { try { - return new IOSDriver(new URL("http://" + ip + ":" + PORT + "/wd/hub"), capabilities); + return new IOSDriver(new URL("http://" + ip + ":" + PORT + "/wd/hub"), options); } catch (MalformedURLException e) { throw new RuntimeException(e); } @@ -63,7 +58,7 @@ public static void beforeClass() throws IOException { } catch (SessionNotCreatedException e) { // Sometimes WDA session creation freezes unexpectedly on CI: // https://dev.azure.com/srinivasansekar/java-client/_build/results?buildId=356&view=ms.vss-test-web.build-test-results-tab - capabilities.setCapability("useNewWDA", true); + options.useNewWDA(); driver = createDriver.get(); } } diff --git a/src/test/java/io/appium/java_client/ios/BaseSafariTest.java b/src/test/java/io/appium/java_client/ios/BaseSafariTest.java index 122d30257..0dd44f2a6 100644 --- a/src/test/java/io/appium/java_client/ios/BaseSafariTest.java +++ b/src/test/java/io/appium/java_client/ios/BaseSafariTest.java @@ -16,13 +16,10 @@ package io.appium.java_client.ios; -import io.appium.java_client.remote.AutomationName; -import io.appium.java_client.remote.IOSMobileCapabilityType; +import io.appium.java_client.ios.options.XCUITestOptions; import io.appium.java_client.remote.MobileBrowserType; -import io.appium.java_client.remote.MobileCapabilityType; import io.appium.java_client.service.local.AppiumServerHasNotBeenStartedLocallyException; import org.junit.BeforeClass; -import org.openqa.selenium.remote.DesiredCapabilities; import java.io.IOException; import java.net.URL; @@ -36,14 +33,11 @@ public class BaseSafariTest extends BaseIOSTest { throw new AppiumServerHasNotBeenStartedLocallyException("An appium server node is not started!"); } - DesiredCapabilities capabilities = new DesiredCapabilities(); - capabilities.setCapability(MobileCapabilityType.BROWSER_NAME, MobileBrowserType.SAFARI); - capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, AutomationName.IOS_XCUI_TEST); - capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, PLATFORM_VERSION); - //sometimes environment has performance problems - capabilities.setCapability(IOSMobileCapabilityType.WDA_LAUNCH_TIMEOUT, - WDA_LAUNCH_TIMEOUT.toMillis()); - capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, DEVICE_NAME); - driver = new IOSDriver(new URL("http://" + ip + ":" + PORT + "/wd/hub"), capabilities); + XCUITestOptions options = new XCUITestOptions() + .withBrowserName(MobileBrowserType.SAFARI) + .setDeviceName(DEVICE_NAME) + .setPlatformVersion(PLATFORM_VERSION) + .setWdaLaunchTimeout(WDA_LAUNCH_TIMEOUT); + driver = new IOSDriver(new URL("http://" + ip + ":" + PORT + "/wd/hub"), options); } } diff --git a/src/test/java/io/appium/java_client/pagefactory_tests/MobileBrowserCompatibilityTest.java b/src/test/java/io/appium/java_client/pagefactory_tests/MobileBrowserCompatibilityTest.java index 8c4b5cf30..d9f4b6707 100644 --- a/src/test/java/io/appium/java_client/pagefactory_tests/MobileBrowserCompatibilityTest.java +++ b/src/test/java/io/appium/java_client/pagefactory_tests/MobileBrowserCompatibilityTest.java @@ -19,10 +19,10 @@ import static java.time.Duration.ofSeconds; import io.appium.java_client.android.AndroidDriver; +import io.appium.java_client.android.options.UiAutomator2Options; import io.appium.java_client.pagefactory.AndroidFindBy; import io.appium.java_client.pagefactory.AppiumFieldDecorator; import io.appium.java_client.remote.MobileBrowserType; -import io.appium.java_client.remote.MobileCapabilityType; import io.appium.java_client.service.local.AppiumDriverLocalService; import org.junit.After; import org.junit.Assert; @@ -30,7 +30,6 @@ import org.junit.Test; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; -import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.remote.RemoteWebElement; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBys; @@ -44,7 +43,8 @@ public class MobileBrowserCompatibilityTest { private AppiumDriverLocalService service; - @AndroidFindBy(className = "someClass") @AndroidFindBy(xpath = "//someTag") + @AndroidFindBy(className = "someClass") + @AndroidFindBy(xpath = "//someTag") private RemoteWebElement btnG; //this element should be found by id = 'btnG' or name = 'btnG' @FindBy(name = "q") @@ -53,20 +53,20 @@ public class MobileBrowserCompatibilityTest { @AndroidFindBy(className = "someClass") @FindBys({@FindBy(className = "r"), @FindBy(tagName = "a")}) - private List - foundLinks; + private List foundLinks; /** * The setting up. */ - @Before public void setUp() { + @Before + public void setUp() { service = AppiumDriverLocalService.buildDefaultService(); service.start(); - DesiredCapabilities capabilities = new DesiredCapabilities(); - capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "Android Emulator"); - capabilities.setCapability(MobileCapabilityType.BROWSER_NAME, MobileBrowserType.BROWSER); - driver = new AndroidDriver(service.getUrl(), capabilities); + UiAutomator2Options options = new UiAutomator2Options() + .withBrowserName(MobileBrowserType.BROWSER) + .setDeviceName("Android Emulator"); + driver = new AndroidDriver(service.getUrl(), options); //This time out is set because test can be run on slow Android SDK emulator PageFactory.initElements(new AppiumFieldDecorator(driver, ofSeconds(5)), this); } @@ -74,7 +74,8 @@ public class MobileBrowserCompatibilityTest { /** * finishing. */ - @After public void tearDown() { + @After + public void tearDown() { if (driver != null) { driver.quit(); } @@ -84,7 +85,8 @@ public class MobileBrowserCompatibilityTest { } } - @Test public void test() { + @Test + public void test() { driver.get("https://www.google.com"); searchTextField.sendKeys("Hello"); diff --git a/src/test/java/io/appium/java_client/service/local/ServerBuilderTest.java b/src/test/java/io/appium/java_client/service/local/ServerBuilderTest.java index 48e4671b4..ea8a7c706 100644 --- a/src/test/java/io/appium/java_client/service/local/ServerBuilderTest.java +++ b/src/test/java/io/appium/java_client/service/local/ServerBuilderTest.java @@ -2,13 +2,6 @@ import static io.appium.java_client.TestResources.apiDemosApk; import static io.appium.java_client.TestUtils.getLocalIp4Address; -import static io.appium.java_client.remote.AndroidMobileCapabilityType.APP_ACTIVITY; -import static io.appium.java_client.remote.AndroidMobileCapabilityType.APP_PACKAGE; -import static io.appium.java_client.remote.AndroidMobileCapabilityType.CHROMEDRIVER_EXECUTABLE; -import static io.appium.java_client.remote.MobileCapabilityType.APP; -import static io.appium.java_client.remote.MobileCapabilityType.FULL_RESET; -import static io.appium.java_client.remote.MobileCapabilityType.NEW_COMMAND_TIMEOUT; -import static io.appium.java_client.remote.MobileCapabilityType.PLATFORM_NAME; import static io.appium.java_client.service.local.AppiumDriverLocalService.buildDefaultService; import static io.appium.java_client.service.local.AppiumServiceBuilder.APPIUM_PATH; import static io.appium.java_client.service.local.flags.GeneralServerFlag.CALLBACK_ADDRESS; @@ -29,19 +22,21 @@ import static org.junit.Assert.assertTrue; import com.google.common.collect.ImmutableMap; +import io.appium.java_client.android.options.UiAutomator2Options; import io.github.bonigarcia.wdm.WebDriverManager; import org.junit.After; import org.junit.BeforeClass; import org.junit.Test; -import org.openqa.selenium.remote.DesiredCapabilities; import java.io.File; import java.io.FileOutputStream; import java.io.OutputStream; import java.nio.file.Path; +import java.time.Duration; import java.util.ArrayList; import java.util.List; +@SuppressWarnings("ResultOfMethodCallIgnored") public class ServerBuilderTest { /** @@ -154,16 +149,15 @@ public void checkAbilityToStartServiceUsingFlags() { @Test public void checkAbilityToStartServiceUsingCapabilities() { - DesiredCapabilities caps = new DesiredCapabilities(); - caps.setCapability(PLATFORM_NAME, "Android"); - caps.setCapability(FULL_RESET, true); - caps.setCapability(NEW_COMMAND_TIMEOUT, 60); - caps.setCapability(APP_PACKAGE, "io.appium.android.apis"); - caps.setCapability(APP_ACTIVITY, ".view.WebView1"); - caps.setCapability(APP, apiDemosApk().toAbsolutePath().toString()); - caps.setCapability(CHROMEDRIVER_EXECUTABLE, chromeManager.getDownloadedDriverPath()); - - service = new AppiumServiceBuilder().withCapabilities(caps).build(); + UiAutomator2Options options = new UiAutomator2Options() + .fullReset() + .setNewCommandTimeout(Duration.ofSeconds(60)) + .setAppPackage("io.appium.android.apis") + .setAppActivity(".view.WebView1") + .setApp(apiDemosApk().toAbsolutePath().toString()) + .setChromedriverExecutable(chromeManager.getDownloadedDriverPath()); + + service = new AppiumServiceBuilder().withCapabilities(options).build(); service.start(); assertTrue(service.isRunning()); } @@ -172,25 +166,25 @@ public void checkAbilityToStartServiceUsingCapabilities() { public void checkAbilityToStartServiceUsingCapabilitiesAndFlags() { File app = ROOT_TEST_PATH.resolve("ApiDemos-debug.apk").toFile(); - DesiredCapabilities caps = new DesiredCapabilities(); - caps.setCapability(PLATFORM_NAME, "Android"); - caps.setCapability(FULL_RESET, true); - caps.setCapability(NEW_COMMAND_TIMEOUT, 60); - caps.setCapability(APP_PACKAGE, "io.appium.android.apis"); - caps.setCapability(APP_ACTIVITY, ".view.WebView1"); - caps.setCapability(APP, app.getAbsolutePath()); - caps.setCapability("winPath", "C:\\selenium\\app.apk"); - caps.setCapability("unixPath", "/selenium/app.apk"); - caps.setCapability("quotes", "\"'"); - caps.setCapability("goog:chromeOptions", - ImmutableMap.of("env", ImmutableMap.of("test", "value"), "val2", 0)); - caps.setCapability(CHROMEDRIVER_EXECUTABLE, chromeManager.getDownloadedDriverPath()); + UiAutomator2Options options = new UiAutomator2Options() + .fullReset() + .setNewCommandTimeout(Duration.ofSeconds(60)) + .setAppPackage("io.appium.android.apis") + .setAppActivity(".view.WebView1") + .setApp(app.getAbsolutePath()) + .setChromedriverExecutable(chromeManager.getDownloadedDriverPath()) + .amend("winPath", "C:\\selenium\\app.apk") + .amend("unixPath", "/selenium/app.apk") + .amend("quotes", "\"'") + .setChromeOptions( + ImmutableMap.of("env", ImmutableMap.of("test", "value"), "val2", 0) + ); service = new AppiumServiceBuilder() .withArgument(CALLBACK_ADDRESS, testIP) .withArgument(SESSION_OVERRIDE) .withArgument(PRE_LAUNCH) - .withCapabilities(caps).build(); + .withCapabilities(options).build(); service.start(); assertTrue(service.isRunning()); } 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 7f0bdf590..a5a7a1c1a 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 @@ -28,15 +28,14 @@ import io.appium.java_client.android.options.UiAutomator2Options; import io.appium.java_client.ios.BaseIOSTest; import io.appium.java_client.ios.IOSDriver; +import io.appium.java_client.ios.options.XCUITestOptions; import io.appium.java_client.remote.AutomationName; -import io.appium.java_client.remote.IOSMobileCapabilityType; import io.appium.java_client.remote.MobileCapabilityType; import io.appium.java_client.remote.MobilePlatform; import io.appium.java_client.service.local.flags.GeneralServerFlag; import io.github.bonigarcia.wdm.WebDriverManager; import org.junit.Test; import org.openqa.selenium.Capabilities; -import org.openqa.selenium.remote.DesiredCapabilities; import java.time.Duration; @@ -121,24 +120,20 @@ public void startingAndroidAppWithCapabilitiesAndFlagsOnServerSideTest() { @Test public void startingIOSAppWithCapabilitiesOnlyTest() { - DesiredCapabilities capabilities = new DesiredCapabilities(); - capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, BaseIOSTest.PLATFORM_VERSION); - //sometimes environment has performance problems - capabilities.setCapability(IOSMobileCapabilityType.WDA_LAUNCH_TIMEOUT, - BaseIOSTest.WDA_LAUNCH_TIMEOUT.toMillis()); - capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, BaseIOSTest.DEVICE_NAME); - capabilities.setCapability(MobileCapabilityType.APP, uiCatalogAppZip().toAbsolutePath().toString()); - capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, AutomationName.IOS_XCUI_TEST); - - IOSDriver driver = new IOSDriver(capabilities); + XCUITestOptions options = new XCUITestOptions() + .setPlatformVersion(BaseIOSTest.PLATFORM_VERSION) + .setDeviceName(BaseIOSTest.DEVICE_NAME) + .setApp(uiCatalogAppZip().toAbsolutePath().toString()) + .setWdaLaunchTimeout(BaseIOSTest.WDA_LAUNCH_TIMEOUT); + IOSDriver driver = new IOSDriver(options); try { - Capabilities caps = driver.getCapabilities(); + XCUITestOptions caps = new XCUITestOptions(driver.getCapabilities()); - assertEquals(AutomationName.IOS_XCUI_TEST, caps.getCapability(MobileCapabilityType.AUTOMATION_NAME)); - assertEquals(MobilePlatform.IOS, caps.getCapability(MobileCapabilityType.PLATFORM_NAME)); - assertNotNull(caps.getCapability(MobileCapabilityType.DEVICE_NAME)); - assertEquals(BaseIOSTest.PLATFORM_VERSION, caps.getCapability(MobileCapabilityType.PLATFORM_VERSION)); - assertEquals(uiCatalogAppZip().toAbsolutePath().toString(), caps.getCapability(MobileCapabilityType.APP)); + assertEquals(AutomationName.IOS_XCUI_TEST, caps.getAutomationName().orElse(null)); + assertTrue(MobilePlatform.IOS.equalsIgnoreCase(caps.getPlatformName().toString())); + assertNotNull(caps.getDeviceName().orElse(null)); + assertEquals(BaseIOSTest.PLATFORM_VERSION, caps.getPlatformVersion().orElse(null)); + assertEquals(uiCatalogAppZip().toAbsolutePath().toString(), caps.getApp().orElse(null)); } finally { driver.quit(); } @@ -147,20 +142,17 @@ public void startingIOSAppWithCapabilitiesOnlyTest() { @Test public void startingIOSAppWithCapabilitiesAndServiceTest() { - DesiredCapabilities capabilities = new DesiredCapabilities(); - capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, BaseIOSTest.DEVICE_NAME); - capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, AutomationName.IOS_XCUI_TEST); - capabilities.setCapability(MobileCapabilityType.APP, uiCatalogAppZip().toAbsolutePath().toString()); - capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, BaseIOSTest.PLATFORM_VERSION); - //sometimes environment has performance problems - capabilities.setCapability(IOSMobileCapabilityType.WDA_LAUNCH_TIMEOUT, - BaseIOSTest.WDA_LAUNCH_TIMEOUT.toMillis()); + XCUITestOptions options = new XCUITestOptions() + .setPlatformVersion(BaseIOSTest.PLATFORM_VERSION) + .setDeviceName(BaseIOSTest.DEVICE_NAME) + .setApp(uiCatalogAppZip().toAbsolutePath().toString()) + .setWdaLaunchTimeout(BaseIOSTest.WDA_LAUNCH_TIMEOUT); AppiumServiceBuilder builder = new AppiumServiceBuilder() .withArgument(GeneralServerFlag.SESSION_OVERRIDE) .withArgument(GeneralServerFlag.STRICT_CAPS); - IOSDriver driver = new IOSDriver(builder, capabilities); + IOSDriver driver = new IOSDriver(builder, options); try { Capabilities caps = driver.getCapabilities(); assertTrue(caps.getCapability(MobileCapabilityType.PLATFORM_NAME) @@ -173,27 +165,24 @@ public void startingIOSAppWithCapabilitiesAndServiceTest() { @Test public void startingIOSAppWithCapabilitiesAndFlagsOnServerSideTest() { - DesiredCapabilities serverCapabilities = new DesiredCapabilities(); - serverCapabilities.setCapability(MobileCapabilityType.DEVICE_NAME, BaseIOSTest.DEVICE_NAME); - serverCapabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, AutomationName.IOS_XCUI_TEST); - serverCapabilities.setCapability(IOSMobileCapabilityType.WDA_LAUNCH_TIMEOUT, - BaseIOSTest.WDA_LAUNCH_TIMEOUT.toMillis()); //some environment is too slow - serverCapabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, BaseIOSTest.PLATFORM_VERSION); - serverCapabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, MobilePlatform.IOS); + XCUITestOptions serverOptions = new XCUITestOptions() + .setPlatformVersion(BaseIOSTest.PLATFORM_VERSION) + .setDeviceName(BaseIOSTest.DEVICE_NAME) + .setWdaLaunchTimeout(BaseIOSTest.WDA_LAUNCH_TIMEOUT); - DesiredCapabilities clientCapabilities = new DesiredCapabilities(); - clientCapabilities.setCapability(MobileCapabilityType.APP, uiCatalogAppZip().toAbsolutePath().toString()); + XCUITestOptions clientOptions = new XCUITestOptions() + .setApp(uiCatalogAppZip().toAbsolutePath().toString()); AppiumServiceBuilder builder = new AppiumServiceBuilder() .withArgument(GeneralServerFlag.SESSION_OVERRIDE) - .withArgument(GeneralServerFlag.STRICT_CAPS).withCapabilities(serverCapabilities); + .withArgument(GeneralServerFlag.STRICT_CAPS) + .withCapabilities(serverOptions); - IOSDriver driver = new IOSDriver(builder, clientCapabilities); + IOSDriver driver = new IOSDriver(builder, clientOptions); try { - Capabilities caps = driver.getCapabilities(); - assertTrue(caps.getCapability(MobileCapabilityType.PLATFORM_NAME) - .toString().equalsIgnoreCase(MobilePlatform.IOS)); - assertNotNull(caps.getCapability(MobileCapabilityType.DEVICE_NAME)); + XCUITestOptions caps = new XCUITestOptions(driver.getCapabilities()); + assertTrue(MobilePlatform.IOS.equalsIgnoreCase(caps.getPlatformName().toString())); + assertNotNull(caps.getDeviceName().orElse(null)); assertFalse(driver.isBrowser()); } finally { driver.quit(); From a4088dd96cb8e423b4d799719420c8f5578a4658 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Thu, 28 Oct 2021 12:05:24 +0200 Subject: [PATCH 3/5] Add missing dot --- .../other/SupportsLaunchWithIdbOption.java | 2 +- .../remote/options/BaseOptions.java | 21 +++++++++++++++++++ .../service/local/StartingAppLocallyTest.java | 5 +++-- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/main/java/io/appium/java_client/ios/options/other/SupportsLaunchWithIdbOption.java b/src/main/java/io/appium/java_client/ios/options/other/SupportsLaunchWithIdbOption.java index e4f910072..8c36b58bf 100644 --- a/src/main/java/io/appium/java_client/ios/options/other/SupportsLaunchWithIdbOption.java +++ b/src/main/java/io/appium/java_client/ios/options/other/SupportsLaunchWithIdbOption.java @@ -52,7 +52,7 @@ default T setLaunchWithIdb(boolean value) { } /** - * Get whether to launch WebDriverAgentRunner with idb instead of xcodebuild + * Get whether to launch WebDriverAgentRunner with idb instead of xcodebuild. * * @return True or false. */ diff --git a/src/main/java/io/appium/java_client/remote/options/BaseOptions.java b/src/main/java/io/appium/java_client/remote/options/BaseOptions.java index 16fb34232..872f87a78 100644 --- a/src/main/java/io/appium/java_client/remote/options/BaseOptions.java +++ b/src/main/java/io/appium/java_client/remote/options/BaseOptions.java @@ -18,6 +18,8 @@ import org.openqa.selenium.Capabilities; import org.openqa.selenium.MutableCapabilities; +import org.openqa.selenium.Platform; +import org.openqa.selenium.WebDriverException; import org.openqa.selenium.internal.Require; import org.openqa.selenium.remote.AcceptedW3CCapabilityKeys; import org.openqa.selenium.remote.CapabilityType; @@ -26,6 +28,7 @@ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.Map; +import java.util.Optional; import java.util.stream.Collectors; import static io.appium.java_client.internal.CapabilityHelpers.APPIUM_PREFIX; @@ -76,6 +79,24 @@ public T setPlatformName(String platform) { return amend(CapabilityType.PLATFORM_NAME, platform); } + @Override + @Nullable + public Platform getPlatformName() { + return Optional.ofNullable(getCapability(CapabilityType.PLATFORM_NAME)) + .map(cap -> { + if (cap instanceof Platform) { + return (Platform) cap; + } + + try { + return Platform.fromString((String.valueOf(cap))); + } catch (WebDriverException e) { + return null; + } + }) + .orElse(null); + } + @Override public Map asMap() { return unmodifiableMap(super.asMap().entrySet().stream() 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 a5a7a1c1a..467d6c21f 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 @@ -36,6 +36,7 @@ import io.github.bonigarcia.wdm.WebDriverManager; import org.junit.Test; import org.openqa.selenium.Capabilities; +import org.openqa.selenium.Platform; import java.time.Duration; @@ -130,7 +131,7 @@ public void startingIOSAppWithCapabilitiesOnlyTest() { XCUITestOptions caps = new XCUITestOptions(driver.getCapabilities()); assertEquals(AutomationName.IOS_XCUI_TEST, caps.getAutomationName().orElse(null)); - assertTrue(MobilePlatform.IOS.equalsIgnoreCase(caps.getPlatformName().toString())); + assertEquals(Platform.IOS, caps.getPlatformName()); assertNotNull(caps.getDeviceName().orElse(null)); assertEquals(BaseIOSTest.PLATFORM_VERSION, caps.getPlatformVersion().orElse(null)); assertEquals(uiCatalogAppZip().toAbsolutePath().toString(), caps.getApp().orElse(null)); @@ -181,7 +182,7 @@ public void startingIOSAppWithCapabilitiesAndFlagsOnServerSideTest() { IOSDriver driver = new IOSDriver(builder, clientOptions); try { XCUITestOptions caps = new XCUITestOptions(driver.getCapabilities()); - assertTrue(MobilePlatform.IOS.equalsIgnoreCase(caps.getPlatformName().toString())); + assertEquals(Platform.IOS, caps.getPlatformName()); assertNotNull(caps.getDeviceName().orElse(null)); assertFalse(driver.isBrowser()); } finally { From b733e5d649b36f1248cc52bcd4e9052564b214af Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Thu, 28 Oct 2021 12:47:07 +0200 Subject: [PATCH 4/5] Fix capabilities handling --- src/main/java/io/appium/java_client/AppiumDriver.java | 11 ++++++++++- .../android/options/UiAutomator2Options.java | 7 +++++++ .../java_client/ios/options/XCUITestOptions.java | 7 +++++++ .../java_client/remote/options/BaseOptions.java | 9 +++++++++ 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/main/java/io/appium/java_client/AppiumDriver.java b/src/main/java/io/appium/java_client/AppiumDriver.java index cd987ca94..31f68b353 100644 --- a/src/main/java/io/appium/java_client/AppiumDriver.java +++ b/src/main/java/io/appium/java_client/AppiumDriver.java @@ -17,10 +17,12 @@ package io.appium.java_client; import static io.appium.java_client.remote.MobileCapabilityType.PLATFORM_NAME; +import static org.apache.commons.lang3.StringUtils.isBlank; import io.appium.java_client.remote.AppiumCommandExecutor; import io.appium.java_client.remote.AppiumNewSessionCommandPayload; import io.appium.java_client.remote.MobileCapabilityType; +import io.appium.java_client.remote.options.BaseOptions; import io.appium.java_client.service.local.AppiumDriverLocalService; import io.appium.java_client.service.local.AppiumServiceBuilder; import org.openqa.selenium.Capabilities; @@ -28,6 +30,7 @@ import org.openqa.selenium.MutableCapabilities; import org.openqa.selenium.SessionNotCreatedException; import org.openqa.selenium.WebDriverException; +import org.openqa.selenium.remote.CapabilityType; import org.openqa.selenium.remote.DriverCommand; import org.openqa.selenium.remote.ErrorHandler; import org.openqa.selenium.remote.ExecuteMethod; @@ -199,7 +202,13 @@ protected void startSession(Capabilities capabilities) { } @SuppressWarnings("unchecked") Map rawCapabilities = (Map) responseValue; - MutableCapabilities returnedCapabilities = new MutableCapabilities(rawCapabilities); + // A workaround for Selenium API enforcing some legacy capability values + rawCapabilities.remove(CapabilityType.PLATFORM); + if (rawCapabilities.containsKey(CapabilityType.BROWSER_NAME) + && isBlank((String) rawCapabilities.get(CapabilityType.BROWSER_NAME))) { + rawCapabilities.remove(CapabilityType.BROWSER_NAME); + } + MutableCapabilities returnedCapabilities = new BaseOptions<>(rawCapabilities); try { Field capsField = RemoteWebDriver.class.getDeclaredField("capabilities"); capsField.setAccessible(true); diff --git a/src/main/java/io/appium/java_client/android/options/UiAutomator2Options.java b/src/main/java/io/appium/java_client/android/options/UiAutomator2Options.java index 6520cd672..dc4b7a74c 100644 --- a/src/main/java/io/appium/java_client/android/options/UiAutomator2Options.java +++ b/src/main/java/io/appium/java_client/android/options/UiAutomator2Options.java @@ -104,6 +104,8 @@ import io.appium.java_client.remote.options.SupportsUdidOption; import org.openqa.selenium.Capabilities; +import java.util.Map; + /** * https://github.com/appium/appium-uiautomator2-driver#capabilities */ @@ -211,6 +213,11 @@ public UiAutomator2Options(Capabilities source) { setCommonOptions(); } + public UiAutomator2Options(Map source) { + super(source); + setCommonOptions(); + } + private void setCommonOptions() { setPlatformName(MobilePlatform.ANDROID); setAutomationName(AutomationName.ANDROID_UIAUTOMATOR2); diff --git a/src/main/java/io/appium/java_client/ios/options/XCUITestOptions.java b/src/main/java/io/appium/java_client/ios/options/XCUITestOptions.java index e558d602a..2eb61386d 100644 --- a/src/main/java/io/appium/java_client/ios/options/XCUITestOptions.java +++ b/src/main/java/io/appium/java_client/ios/options/XCUITestOptions.java @@ -115,6 +115,8 @@ import io.appium.java_client.remote.options.SupportsUdidOption; import org.openqa.selenium.Capabilities; +import java.util.Map; + /** * https://github.com/appium/appium-xcuitest-driver#capabilities */ @@ -230,6 +232,11 @@ public XCUITestOptions(Capabilities source) { setCommonOptions(); } + public XCUITestOptions(Map source) { + super(source); + setCommonOptions(); + } + private void setCommonOptions() { setPlatformName(MobilePlatform.IOS); setAutomationName(AutomationName.IOS_XCUI_TEST); diff --git a/src/main/java/io/appium/java_client/remote/options/BaseOptions.java b/src/main/java/io/appium/java_client/remote/options/BaseOptions.java index 872f87a78..bfa8c3cc4 100644 --- a/src/main/java/io/appium/java_client/remote/options/BaseOptions.java +++ b/src/main/java/io/appium/java_client/remote/options/BaseOptions.java @@ -59,6 +59,15 @@ public class BaseOptions> extends MutableCapabilities i public BaseOptions() { } + /** + * Creates new instance with provided capabilities. + * + * @param source Capabilities map to merge into new instance + */ + public BaseOptions(Map source) { + super(source); + } + /** * Creates new instance with provided capabilities. * From 8533eaeac4dcb5624e938dc5ff4b86d41053533e Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Thu, 28 Oct 2021 14:42:06 +0200 Subject: [PATCH 5/5] Update the test --- .../appium/java_client/ios/IOSWebViewTest.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) 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 5f8564ccb..4afb89cd1 100644 --- a/src/test/java/io/appium/java_client/ios/IOSWebViewTest.java +++ b/src/test/java/io/appium/java_client/ios/IOSWebViewTest.java @@ -7,21 +7,23 @@ import io.appium.java_client.AppiumBy; import org.junit.Test; import org.openqa.selenium.By; -import org.openqa.selenium.WebElement; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; public class IOSWebViewTest extends BaseIOSWebViewTest { + private static final Duration LOOKUP_TIMEOUT = Duration.ofSeconds(30); - @Test public void webViewPageTestCase() throws InterruptedException { - new WebDriverWait(driver, Duration.ofSeconds(30)) + @Test + public void webViewPageTestCase() throws InterruptedException { + new WebDriverWait(driver, LOOKUP_TIMEOUT) .until(ExpectedConditions.presenceOfElementLocated(By.id("login"))) .click(); - driver.findElement(AppiumBy.accessibilityId("webView")).click(); - new WebDriverWait(driver, Duration.ofSeconds(30)) + new WebDriverWait(driver, LOOKUP_TIMEOUT) + .until(ExpectedConditions.presenceOfElementLocated(AppiumBy.accessibilityId("webView"))) + .click(); + new WebDriverWait(driver, LOOKUP_TIMEOUT) .until(ExpectedConditions.presenceOfElementLocated(AppiumBy.accessibilityId("Webview"))); findAndSwitchToWebView(); - WebElement el = driver.findElement(By.partialLinkText("login")); - assertTrue(el.isDisplayed()); + assertTrue(driver.findElement(By.partialLinkText("login")).isDisplayed()); } }