From 28f94e44edf76103709c190b8e0d9deadedeeeb3 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Tue, 26 Oct 2021 14:26:13 +0200 Subject: [PATCH 1/2] chore: Add WDA-related XCUITestOptions --- .../internal/CapabilityHelpers.java | 27 +++++-- .../ios/options/XCUITestOptions.java | 68 +++++++++++++++++- .../app/SupportsAppInstallStrategyOption.java | 10 +-- .../java_client/ios/options/wda/Keychain.java | 27 +++++++ .../ios/options/wda/ProcessArguments.java | 56 +++++++++++++++ ...wProvisioningDeviceRegistrationOption.java | 60 ++++++++++++++++ .../wda/SupportsAutoAcceptAlertsOption.java | 59 +++++++++++++++ .../wda/SupportsAutoDismissAlertsOption.java | 59 +++++++++++++++ .../wda/SupportsDerivedDataPathOption.java | 49 +++++++++++++ ...ortsDisableAutomaticScreenshotsOption.java | 51 +++++++++++++ .../wda/SupportsForceAppLaunchOption.java | 53 ++++++++++++++ .../options/wda/SupportsKeychainOptions.java | 54 ++++++++++++++ .../wda/SupportsMaxTypingFrequencyOption.java | 51 +++++++++++++ .../wda/SupportsMjpegServerPortOption.java | 53 ++++++++++++++ .../wda/SupportsProcessArgumentsOption.java | 56 +++++++++++++++ .../wda/SupportsResultBundlePathOption.java | 51 +++++++++++++ .../wda/SupportsScreenshotQualityOption.java | 53 ++++++++++++++ .../wda/SupportsShouldTerminateAppOption.java | 53 ++++++++++++++ ...tsShouldUseSingletonTestManagerOption.java | 59 +++++++++++++++ .../wda/SupportsShowXcodeLogOption.java | 61 ++++++++++++++++ .../SupportsSimpleIsVisibleCheckOption.java | 62 ++++++++++++++++ .../wda/SupportsUpdatedWdaBundleIdOption.java | 48 +++++++++++++ ...upportsUseNativeCachingStrategyOption.java | 52 ++++++++++++++ .../options/wda/SupportsUseNewWdaOption.java | 70 ++++++++++++++++++ .../wda/SupportsUsePrebuiltWdaOption.java | 59 +++++++++++++++ .../wda/SupportsUseSimpleBuildTestOption.java | 60 ++++++++++++++++ .../wda/SupportsUseXctestrunFileOption.java | 69 ++++++++++++++++++ .../wda/SupportsWaitForIdleTimeoutOption.java | 58 +++++++++++++++ .../wda/SupportsWaitForQuiescenceOption.java | 52 ++++++++++++++ .../options/wda/SupportsWdaBaseUrlOption.java | 72 +++++++++++++++++++ .../SupportsWdaConnectionTimeoutOption.java | 52 ++++++++++++++ .../SupportsWdaEventloopIdleDelayOption.java | 59 +++++++++++++++ .../wda/SupportsWdaLaunchTimeoutOption.java | 52 ++++++++++++++ .../wda/SupportsWdaLocalPortOption.java | 52 ++++++++++++++ .../wda/SupportsWdaStartupRetriesOption.java | 50 +++++++++++++ ...SupportsWdaStartupRetryIntervalOption.java | 52 ++++++++++++++ .../wda/SupportsWebDriverAgentUrlOption.java | 68 ++++++++++++++++++ .../wda/SupportsXcodeCertificateOptions.java | 58 +++++++++++++++ .../ios/options/wda/XcodeCertificate.java | 36 ++++++++++ 39 files changed, 2077 insertions(+), 14 deletions(-) create mode 100644 src/main/java/io/appium/java_client/ios/options/wda/Keychain.java create mode 100644 src/main/java/io/appium/java_client/ios/options/wda/ProcessArguments.java create mode 100644 src/main/java/io/appium/java_client/ios/options/wda/SupportsAllowProvisioningDeviceRegistrationOption.java create mode 100644 src/main/java/io/appium/java_client/ios/options/wda/SupportsAutoAcceptAlertsOption.java create mode 100644 src/main/java/io/appium/java_client/ios/options/wda/SupportsAutoDismissAlertsOption.java create mode 100644 src/main/java/io/appium/java_client/ios/options/wda/SupportsDerivedDataPathOption.java create mode 100644 src/main/java/io/appium/java_client/ios/options/wda/SupportsDisableAutomaticScreenshotsOption.java create mode 100644 src/main/java/io/appium/java_client/ios/options/wda/SupportsForceAppLaunchOption.java create mode 100644 src/main/java/io/appium/java_client/ios/options/wda/SupportsKeychainOptions.java create mode 100644 src/main/java/io/appium/java_client/ios/options/wda/SupportsMaxTypingFrequencyOption.java create mode 100644 src/main/java/io/appium/java_client/ios/options/wda/SupportsMjpegServerPortOption.java create mode 100644 src/main/java/io/appium/java_client/ios/options/wda/SupportsProcessArgumentsOption.java create mode 100644 src/main/java/io/appium/java_client/ios/options/wda/SupportsResultBundlePathOption.java create mode 100644 src/main/java/io/appium/java_client/ios/options/wda/SupportsScreenshotQualityOption.java create mode 100644 src/main/java/io/appium/java_client/ios/options/wda/SupportsShouldTerminateAppOption.java create mode 100644 src/main/java/io/appium/java_client/ios/options/wda/SupportsShouldUseSingletonTestManagerOption.java create mode 100644 src/main/java/io/appium/java_client/ios/options/wda/SupportsShowXcodeLogOption.java create mode 100644 src/main/java/io/appium/java_client/ios/options/wda/SupportsSimpleIsVisibleCheckOption.java create mode 100644 src/main/java/io/appium/java_client/ios/options/wda/SupportsUpdatedWdaBundleIdOption.java create mode 100644 src/main/java/io/appium/java_client/ios/options/wda/SupportsUseNativeCachingStrategyOption.java create mode 100644 src/main/java/io/appium/java_client/ios/options/wda/SupportsUseNewWdaOption.java create mode 100644 src/main/java/io/appium/java_client/ios/options/wda/SupportsUsePrebuiltWdaOption.java create mode 100644 src/main/java/io/appium/java_client/ios/options/wda/SupportsUseSimpleBuildTestOption.java create mode 100644 src/main/java/io/appium/java_client/ios/options/wda/SupportsUseXctestrunFileOption.java create mode 100644 src/main/java/io/appium/java_client/ios/options/wda/SupportsWaitForIdleTimeoutOption.java create mode 100644 src/main/java/io/appium/java_client/ios/options/wda/SupportsWaitForQuiescenceOption.java create mode 100644 src/main/java/io/appium/java_client/ios/options/wda/SupportsWdaBaseUrlOption.java create mode 100644 src/main/java/io/appium/java_client/ios/options/wda/SupportsWdaConnectionTimeoutOption.java create mode 100644 src/main/java/io/appium/java_client/ios/options/wda/SupportsWdaEventloopIdleDelayOption.java create mode 100644 src/main/java/io/appium/java_client/ios/options/wda/SupportsWdaLaunchTimeoutOption.java create mode 100644 src/main/java/io/appium/java_client/ios/options/wda/SupportsWdaLocalPortOption.java create mode 100644 src/main/java/io/appium/java_client/ios/options/wda/SupportsWdaStartupRetriesOption.java create mode 100644 src/main/java/io/appium/java_client/ios/options/wda/SupportsWdaStartupRetryIntervalOption.java create mode 100644 src/main/java/io/appium/java_client/ios/options/wda/SupportsWebDriverAgentUrlOption.java create mode 100644 src/main/java/io/appium/java_client/ios/options/wda/SupportsXcodeCertificateOptions.java create mode 100644 src/main/java/io/appium/java_client/ios/options/wda/XcodeCertificate.java diff --git a/src/main/java/io/appium/java_client/internal/CapabilityHelpers.java b/src/main/java/io/appium/java_client/internal/CapabilityHelpers.java index 106b96c59..86b46bfb0 100644 --- a/src/main/java/io/appium/java_client/internal/CapabilityHelpers.java +++ b/src/main/java/io/appium/java_client/internal/CapabilityHelpers.java @@ -90,8 +90,7 @@ public static Integer toInteger(Object value) { } /** - * Converts generic capability value to long without - * throwing exceptions. + * Converts generic capability value to long. * * @param value The capability value. * @throws NumberFormatException If the given value cannot be parsed to a valid long. @@ -109,8 +108,25 @@ public static Long toLong(Object value) { } /** - * Converts generic capability value to duration without - * throwing exceptions. The value is assumed to be + * Converts generic capability value to double. + * + * @param value The capability value. + * @throws NumberFormatException If the given value cannot be parsed to a valid long. + * @return null is the passed value is null otherwise the converted value. + */ + @Nullable + public static Double toDouble(Object value) { + if (value == null) { + return null; + } else if (value instanceof Number) { + return ((Number) value).doubleValue(); + } else { + return Double.parseDouble(String.valueOf(value)); + } + } + + /** + * Converts generic capability value to duration. The value is assumed to be * measured in milliseconds. * * @param value The capability value. @@ -123,8 +139,7 @@ public static Duration toDuration(Object value) { } /** - * Converts generic capability value to duration without - * throwing exceptions. + * Converts generic capability value to duration. * * @param value The capability value. * @param converter Converts the numeric value to a Duration instance. 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 6a2542fc4..be0bd03be 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,39 @@ 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.wda.SupportsAllowProvisioningDeviceRegistrationOption; +import io.appium.java_client.ios.options.wda.SupportsAutoAcceptAlertsOption; +import io.appium.java_client.ios.options.wda.SupportsAutoDismissAlertsOption; +import io.appium.java_client.ios.options.wda.SupportsDerivedDataPathOption; +import io.appium.java_client.ios.options.wda.SupportsDisableAutomaticScreenshotsOption; +import io.appium.java_client.ios.options.wda.SupportsForceAppLaunchOption; +import io.appium.java_client.ios.options.wda.SupportsKeychainOptions; +import io.appium.java_client.ios.options.wda.SupportsMaxTypingFrequencyOption; +import io.appium.java_client.ios.options.wda.SupportsMjpegServerPortOption; +import io.appium.java_client.ios.options.wda.SupportsProcessArgumentsOption; +import io.appium.java_client.ios.options.wda.SupportsResultBundlePathOption; +import io.appium.java_client.ios.options.wda.SupportsScreenshotQualityOption; +import io.appium.java_client.ios.options.wda.SupportsShouldTerminateAppOption; +import io.appium.java_client.ios.options.wda.SupportsShouldUseSingletonTestManagerOption; +import io.appium.java_client.ios.options.wda.SupportsShowXcodeLogOption; +import io.appium.java_client.ios.options.wda.SupportsSimpleIsVisibleCheckOption; +import io.appium.java_client.ios.options.wda.SupportsUpdatedWdaBundleIdOption; +import io.appium.java_client.ios.options.wda.SupportsUseNativeCachingStrategyOption; +import io.appium.java_client.ios.options.wda.SupportsUseNewWdaOption; +import io.appium.java_client.ios.options.wda.SupportsUsePrebuiltWdaOption; +import io.appium.java_client.ios.options.wda.SupportsUseSimpleBuildTestOption; +import io.appium.java_client.ios.options.wda.SupportsUseXctestrunFileOption; +import io.appium.java_client.ios.options.wda.SupportsWaitForIdleTimeoutOption; +import io.appium.java_client.ios.options.wda.SupportsWaitForQuiescenceOption; +import io.appium.java_client.ios.options.wda.SupportsWdaBaseUrlOption; +import io.appium.java_client.ios.options.wda.SupportsWdaConnectionTimeoutOption; +import io.appium.java_client.ios.options.wda.SupportsWdaEventloopIdleDelayOption; +import io.appium.java_client.ios.options.wda.SupportsWdaLaunchTimeoutOption; +import io.appium.java_client.ios.options.wda.SupportsWdaLocalPortOption; +import io.appium.java_client.ios.options.wda.SupportsWdaStartupRetriesOption; +import io.appium.java_client.ios.options.wda.SupportsWdaStartupRetryIntervalOption; +import io.appium.java_client.ios.options.wda.SupportsWebDriverAgentUrlOption; +import io.appium.java_client.ios.options.wda.SupportsXcodeCertificateOptions; import io.appium.java_client.remote.AutomationName; import io.appium.java_client.remote.MobilePlatform; import io.appium.java_client.remote.options.BaseOptions; @@ -56,7 +89,40 @@ public class XCUITestOptions extends BaseOptions implements SupportsOtherAppsOption, SupportsAppPushTimeoutOption, SupportsAppInstallStrategyOption, - // TODO: WebDriverAgent options: https://github.com/appium/appium-xcuitest-driver#webdriveragent + // WebDriverAgent options: https://github.com/appium/appium-xcuitest-driver#webdriveragent + SupportsXcodeCertificateOptions, + SupportsKeychainOptions, + SupportsUpdatedWdaBundleIdOption, + SupportsDerivedDataPathOption, + SupportsWebDriverAgentUrlOption, + SupportsUseNewWdaOption, + SupportsWdaLaunchTimeoutOption, + SupportsWdaConnectionTimeoutOption, + SupportsWdaStartupRetriesOption, + SupportsWdaStartupRetryIntervalOption, + SupportsWdaLocalPortOption, + SupportsWdaBaseUrlOption, + SupportsShowXcodeLogOption, + SupportsUsePrebuiltWdaOption, + SupportsShouldUseSingletonTestManagerOption, + SupportsWaitForIdleTimeoutOption, + SupportsUseXctestrunFileOption, + SupportsUseSimpleBuildTestOption, + SupportsWdaEventloopIdleDelayOption, + SupportsProcessArgumentsOption, + SupportsAllowProvisioningDeviceRegistrationOption, + SupportsResultBundlePathOption, + SupportsMaxTypingFrequencyOption, + SupportsSimpleIsVisibleCheckOption, + SupportsWaitForQuiescenceOption, + SupportsMjpegServerPortOption, + SupportsScreenshotQualityOption, + SupportsAutoAcceptAlertsOption, + SupportsAutoDismissAlertsOption, + SupportsDisableAutomaticScreenshotsOption, + SupportsShouldTerminateAppOption, + SupportsForceAppLaunchOption, + SupportsUseNativeCachingStrategyOption, // TODO: Simulator options: https://github.com/appium/appium-xcuitest-driver#simulator SupportsOrientationOption, // TODO: Web context options: https://github.com/appium/appium-xcuitest-driver#web-context diff --git a/src/main/java/io/appium/java_client/ios/options/app/SupportsAppInstallStrategyOption.java b/src/main/java/io/appium/java_client/ios/options/app/SupportsAppInstallStrategyOption.java index 313253491..f74d1db15 100644 --- a/src/main/java/io/appium/java_client/ios/options/app/SupportsAppInstallStrategyOption.java +++ b/src/main/java/io/appium/java_client/ios/options/app/SupportsAppInstallStrategyOption.java @@ -29,17 +29,13 @@ public interface SupportsAppInstallStrategyOption> exte /** * Select application installation strategy for real devices. The following * strategies are supported: - * - * serial (default) - pushes app files to the device in a sequential order; + * * serial (default) - pushes app files to the device in a sequential order; * this is the least performant strategy, although the most reliable; - * - * parallel - pushes app files simultaneously; this is usually the + * * parallel - pushes app files simultaneously; this is usually the * most performant strategy, but sometimes could not be very stable; - * - * ios-deploy - tells the driver to use a third-party tool ios-deploy to + * * ios-deploy - tells the driver to use a third-party tool ios-deploy to * install the app; obviously the tool must be installed separately * first and must be present in PATH before it could be used. - * * @param strategy App installation strategy. * @return self instance for chaining. */ diff --git a/src/main/java/io/appium/java_client/ios/options/wda/Keychain.java b/src/main/java/io/appium/java_client/ios/options/wda/Keychain.java new file mode 100644 index 000000000..8a2e69891 --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/wda/Keychain.java @@ -0,0 +1,27 @@ +/* + * 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.wda; + +import lombok.Data; +import lombok.ToString; + +@ToString() +@Data() +public class Keychain { + private final String path; + private final String password; +} diff --git a/src/main/java/io/appium/java_client/ios/options/wda/ProcessArguments.java b/src/main/java/io/appium/java_client/ios/options/wda/ProcessArguments.java new file mode 100644 index 000000000..c5ed74d22 --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/wda/ProcessArguments.java @@ -0,0 +1,56 @@ +/* + * 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.wda; + +import lombok.ToString; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +@ToString() +public class ProcessArguments { + private final List args; + private final Map env; + + public ProcessArguments(List args, Map env) { + this.args = args; + this.env = env; + } + + public ProcessArguments(List args) { + this(args, null); + } + + public ProcessArguments(Map env) { + this(null, env); + } + + /** + * Returns the data object content as a map. + * + * @return Properties as a map. + */ + public Map toMap() { + Map result = new HashMap<>(); + Optional.ofNullable(args).ifPresent((v) -> result.put("args", v)); + Optional.ofNullable(env).ifPresent((v) -> result.put("env", v)); + return Collections.unmodifiableMap(result); + } +} diff --git a/src/main/java/io/appium/java_client/ios/options/wda/SupportsAllowProvisioningDeviceRegistrationOption.java b/src/main/java/io/appium/java_client/ios/options/wda/SupportsAllowProvisioningDeviceRegistrationOption.java new file mode 100644 index 000000000..0ddf36ddb --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/wda/SupportsAllowProvisioningDeviceRegistrationOption.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.wda; + +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 SupportsAllowProvisioningDeviceRegistrationOption> extends + Capabilities, CanSetCapability { + String ALLOW_PROVISIONING_DEVICE_REGISTRATION_OPTION = "allowProvisioningDeviceRegistration"; + + /** + * Allows xcodebuild to register your destination device on the developer portal. + * + * @return self instance for chaining. + */ + default T allowProvisioningDeviceRegistration() { + return amend(ALLOW_PROVISIONING_DEVICE_REGISTRATION_OPTION, true); + } + + /** + * Allow xcodebuild to register your destination device on the developer portal + * if necessary. Requires a developer account to have been added in Xcode's Accounts + * preference pane. Defaults to false. + * + * @param value Whether to allow xcodebuild to register your destination device on the developer portal. + * @return self instance for chaining. + */ + default T setAllowProvisioningDeviceRegistration(boolean value) { + return amend(ALLOW_PROVISIONING_DEVICE_REGISTRATION_OPTION, value); + } + + /** + * Get whether to allow xcodebuild to register your destination device on the developer portal. + * + * @return True or false. + */ + default Optional doesAllowProvisioningDeviceRegistration() { + return Optional.ofNullable(toSafeBoolean(getCapability(ALLOW_PROVISIONING_DEVICE_REGISTRATION_OPTION))); + } +} diff --git a/src/main/java/io/appium/java_client/ios/options/wda/SupportsAutoAcceptAlertsOption.java b/src/main/java/io/appium/java_client/ios/options/wda/SupportsAutoAcceptAlertsOption.java new file mode 100644 index 000000000..1a3a86347 --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/wda/SupportsAutoAcceptAlertsOption.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.wda; + +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 SupportsAutoAcceptAlertsOption> extends + Capabilities, CanSetCapability { + String AUTO_ACCEPT_ALERTS_OPTION = "autoAcceptAlerts"; + + /** + * Enforce to accept all alerts automatically. + * + * @return self instance for chaining. + */ + default T autoAcceptAlerts() { + return amend(AUTO_ACCEPT_ALERTS_OPTION, true); + } + + /** + * Accept all iOS alerts automatically if they pop up. This includes privacy + * access permission alerts (e.g., location, contacts, photos). Default is false. + * + * @param value Whether to accepts alerts automatically. + * @return self instance for chaining. + */ + default T setAutoAcceptAlerts(boolean value) { + return amend(AUTO_ACCEPT_ALERTS_OPTION, value); + } + + /** + * Get whether to accept all alerts automatically. + * + * @return True or false. + */ + default Optional doesAutoAcceptAlerts() { + return Optional.ofNullable(toSafeBoolean(getCapability(AUTO_ACCEPT_ALERTS_OPTION))); + } +} diff --git a/src/main/java/io/appium/java_client/ios/options/wda/SupportsAutoDismissAlertsOption.java b/src/main/java/io/appium/java_client/ios/options/wda/SupportsAutoDismissAlertsOption.java new file mode 100644 index 000000000..82a85754e --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/wda/SupportsAutoDismissAlertsOption.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.wda; + +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 SupportsAutoDismissAlertsOption> extends + Capabilities, CanSetCapability { + String AUTO_DISMISS_ALERTS_OPTION = "autoDismissAlerts"; + + /** + * Enforce to dismiss all alerts automatically. + * + * @return self instance for chaining. + */ + default T autoDismissAlerts() { + return amend(AUTO_DISMISS_ALERTS_OPTION, true); + } + + /** + * Dismiss all iOS alerts automatically if they pop up. This includes privacy + * access permission alerts (e.g., location, contacts, photos). Default is false. + * + * @param value Whether to dismiss alerts automatically. + * @return self instance for chaining. + */ + default T setAutoDismissAlerts(boolean value) { + return amend(AUTO_DISMISS_ALERTS_OPTION, value); + } + + /** + * Get whether to dismiss all alerts automatically. + * + * @return True or false. + */ + default Optional doesAutoDismissAlerts() { + return Optional.ofNullable(toSafeBoolean(getCapability(AUTO_DISMISS_ALERTS_OPTION))); + } +} diff --git a/src/main/java/io/appium/java_client/ios/options/wda/SupportsDerivedDataPathOption.java b/src/main/java/io/appium/java_client/ios/options/wda/SupportsDerivedDataPathOption.java new file mode 100644 index 000000000..e3bfc1f2f --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/wda/SupportsDerivedDataPathOption.java @@ -0,0 +1,49 @@ +/* + * 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.wda; + +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 SupportsDerivedDataPathOption> extends + Capabilities, CanSetCapability { + String DERIVED_DATA_PATH_OPTION = "derivedDataPath"; + + /** + * Use along with usePrebuiltWDA capability and choose where to search for the existing WDA app. If the capability + * is not set then Xcode will store the derived data in the default root taken from preferences. + * It also makes sense to choose different folders for parallel WDA sessions. + * + * @param path Derived data folder path. + * @return self instance for chaining. + */ + default T setDerivedDataPath(String path) { + return amend(DERIVED_DATA_PATH_OPTION, path); + } + + /** + * Get the path to the derived data WDA folder. + * + * @return Derived data folder path. + */ + default Optional getDerivedDataPath() { + return Optional.ofNullable((String) getCapability(DERIVED_DATA_PATH_OPTION)); + } +} diff --git a/src/main/java/io/appium/java_client/ios/options/wda/SupportsDisableAutomaticScreenshotsOption.java b/src/main/java/io/appium/java_client/ios/options/wda/SupportsDisableAutomaticScreenshotsOption.java new file mode 100644 index 000000000..90c0b2683 --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/wda/SupportsDisableAutomaticScreenshotsOption.java @@ -0,0 +1,51 @@ +/* + * 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.wda; + +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 SupportsDisableAutomaticScreenshotsOption> extends + Capabilities, CanSetCapability { + String DISABLE_AUTOMATIC_SCREENSHOTS_OPTION = "disableAutomaticScreenshots"; + + /** + * Disable automatic screenshots taken by XCTest at every interaction. + * Default is up to WebDriverAgent's config to decide, which currently + * defaults to true. + * + * @param value Whether to disable automatic XCTest screenshots. + * @return self instance for chaining. + */ + default T setDisableAutomaticScreenshots(boolean value) { + return amend(DISABLE_AUTOMATIC_SCREENSHOTS_OPTION, value); + } + + /** + * Get whether to disable automatic XCTest screenshots. + * + * @return True or false. + */ + default Optional doesDisableAutomaticScreenshots() { + return Optional.ofNullable(toSafeBoolean(getCapability(DISABLE_AUTOMATIC_SCREENSHOTS_OPTION))); + } +} diff --git a/src/main/java/io/appium/java_client/ios/options/wda/SupportsForceAppLaunchOption.java b/src/main/java/io/appium/java_client/ios/options/wda/SupportsForceAppLaunchOption.java new file mode 100644 index 000000000..4c2ab4780 --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/wda/SupportsForceAppLaunchOption.java @@ -0,0 +1,53 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.appium.java_client.ios.options.wda; + +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 SupportsForceAppLaunchOption> extends + Capabilities, CanSetCapability { + String FORCE_APP_LAUNCH_OPTION = "forceAppLaunch"; + + /** + * Specify if the app should be forcefully restarted if it is already + * running on session startup. This capability only has an effect if an + * application identifier has been passed to the test session (either + * explicitly, by setting bundleId, or implicitly, by providing app). + * Default is true unless noReset capability is set to true. + * + * @param value Whether to enforce app restart on session startup. + * @return self instance for chaining. + */ + default T setForceAppLaunch(boolean value) { + return amend(FORCE_APP_LAUNCH_OPTION, value); + } + + /** + * Get whether to enforce app restart on session startup. + * + * @return True or false. + */ + default Optional doesForceAppLaunch() { + return Optional.ofNullable(toSafeBoolean(getCapability(FORCE_APP_LAUNCH_OPTION))); + } +} diff --git a/src/main/java/io/appium/java_client/ios/options/wda/SupportsKeychainOptions.java b/src/main/java/io/appium/java_client/ios/options/wda/SupportsKeychainOptions.java new file mode 100644 index 000000000..92e7a33bf --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/wda/SupportsKeychainOptions.java @@ -0,0 +1,54 @@ +/* + * 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.wda; + +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 SupportsKeychainOptions> extends + Capabilities, CanSetCapability { + String KEYCHAIN_PATH_OPTION = "keychainPath"; + String KEYCHAIN_PASSWORD_OPTION = "keychainPassword"; + + /** + * Provides details to access custom keychain, which + * contains the private development key exported from the system keychain. + * + * @param keychain Keychain access properties. + * @return self instance for chaining. + */ + default T setKeychain(Keychain keychain) { + return amend(KEYCHAIN_PATH_OPTION, keychain.getPath()) + .amend(KEYCHAIN_PASSWORD_OPTION, keychain.getPassword()); + } + + /** + * Get details to access custom keychain. + * + * @return Keychain access properties + */ + default Optional getKeychain() { + String path = (String) getCapability(KEYCHAIN_PATH_OPTION); + String password = (String) getCapability(KEYCHAIN_PASSWORD_OPTION); + return path == null || password == null + ? Optional.empty() + : Optional.of(new Keychain(path, password)); + } +} diff --git a/src/main/java/io/appium/java_client/ios/options/wda/SupportsMaxTypingFrequencyOption.java b/src/main/java/io/appium/java_client/ios/options/wda/SupportsMaxTypingFrequencyOption.java new file mode 100644 index 000000000..bbc434838 --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/wda/SupportsMaxTypingFrequencyOption.java @@ -0,0 +1,51 @@ +/* + * 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.wda; + +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.toInteger; + +public interface SupportsMaxTypingFrequencyOption> extends + Capabilities, CanSetCapability { + String MAX_TYPING_FREQUENCY_OPTION = "maxTypingFrequency"; + + /** + * Maximum frequency of keystrokes for typing and clear. If your tests + * are failing because of typing errors, you may want to adjust this. + * Defaults to 60 keystrokes per minute. + * + * @param frequency The number of keystrokes per minute. + * @return self instance for chaining. + */ + default T setMaxTypingFrequency(int frequency) { + return amend(MAX_TYPING_FREQUENCY_OPTION, frequency); + } + + /** + * Get the number of keystrokes per minute. + * + * @return The number of keystrokes per minute. + */ + default Optional getMaxTypingFrequency() { + return Optional.ofNullable(toInteger(getCapability(MAX_TYPING_FREQUENCY_OPTION))); + } +} diff --git a/src/main/java/io/appium/java_client/ios/options/wda/SupportsMjpegServerPortOption.java b/src/main/java/io/appium/java_client/ios/options/wda/SupportsMjpegServerPortOption.java new file mode 100644 index 000000000..6b14fab5e --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/wda/SupportsMjpegServerPortOption.java @@ -0,0 +1,53 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.appium.java_client.ios.options.wda; + +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.toInteger; + +public interface SupportsMjpegServerPortOption> extends + Capabilities, CanSetCapability { + String MJPEG_SERVER_PORT_OPTION = "mjpegServerPort"; + + /** + * The port number on which WDA broadcasts screenshots stream encoded into MJPEG + * format from the device under test. It might be necessary to change this value + * if the default port is busy because of other tests running in parallel. + * Default value: 9100. + * + * @param port port number in range 0..65535 + * @return self instance for chaining. + */ + default T setMjpegServerPort(int port) { + return amend(MJPEG_SERVER_PORT_OPTION, port); + } + + /** + * Get the port number on which WDA broadcasts screenshots stream encoded into MJPEG + * format from the device under test. + * + * @return The port number. + */ + default Optional getMjpegServerPort() { + return Optional.ofNullable(toInteger(getCapability(MJPEG_SERVER_PORT_OPTION))); + } +} diff --git a/src/main/java/io/appium/java_client/ios/options/wda/SupportsProcessArgumentsOption.java b/src/main/java/io/appium/java_client/ios/options/wda/SupportsProcessArgumentsOption.java new file mode 100644 index 000000000..2f30a6e1d --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/wda/SupportsProcessArgumentsOption.java @@ -0,0 +1,56 @@ +/* + * 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.wda; + +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.util.List; +import java.util.Map; +import java.util.Optional; + +public interface SupportsProcessArgumentsOption> extends + Capabilities, CanSetCapability { + String PROCESS_ARGUMENTS_OPTION = "processArguments"; + + /** + * Provides process arguments and environment which will be sent + * to the WebDriverAgent server. + * + * @param pa Process arguments. + * @return self instance for chaining. + */ + default T setProcessArguments(ProcessArguments pa) { + return amend(PROCESS_ARGUMENTS_OPTION, pa.toMap()); + } + + /** + * Get process arguments of the app under test. + * + * @return Process arguments. + */ + @SuppressWarnings("unchecked") + default Optional getProcessArguments() { + Map pa = (Map) getCapability(PROCESS_ARGUMENTS_OPTION); + return pa == null || !(pa.containsKey("args") || pa.containsKey("env")) + ? Optional.empty() + : Optional.of(new ProcessArguments( + (List) pa.getOrDefault("args", null), + (Map) pa.getOrDefault("env", null))); + } +} diff --git a/src/main/java/io/appium/java_client/ios/options/wda/SupportsResultBundlePathOption.java b/src/main/java/io/appium/java_client/ios/options/wda/SupportsResultBundlePathOption.java new file mode 100644 index 000000000..01156e770 --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/wda/SupportsResultBundlePathOption.java @@ -0,0 +1,51 @@ +/* + * 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.wda; + +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 SupportsResultBundlePathOption> extends + Capabilities, CanSetCapability { + String RESULT_BUNDLE_PATH_OPTION = "resultBundlePath"; + + /** + * Specify the path to the result bundle path as xcodebuild argument for + * WebDriverAgent build under a security flag. WebDriverAgent process must + * start/stop every time to pick up changed value of this property. + * Specifying useNewWDA to true may help there. Please read man xcodebuild + * for more details. + * + * @param path The path where the resulting XCTest bundle should be stored. + * @return self instance for chaining. + */ + default T setResultBundlePath(String path) { + return amend(RESULT_BUNDLE_PATH_OPTION, path); + } + + /** + * Get the path where the resulting XCTest bundle should be stored. + * + * @return XCTest result bundle path. + */ + default Optional getResultBundlePath() { + return Optional.ofNullable((String) getCapability(RESULT_BUNDLE_PATH_OPTION)); + } +} diff --git a/src/main/java/io/appium/java_client/ios/options/wda/SupportsScreenshotQualityOption.java b/src/main/java/io/appium/java_client/ios/options/wda/SupportsScreenshotQualityOption.java new file mode 100644 index 000000000..0eb3481f7 --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/wda/SupportsScreenshotQualityOption.java @@ -0,0 +1,53 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.appium.java_client.ios.options.wda; + +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.toInteger; + +public interface SupportsScreenshotQualityOption> extends + Capabilities, CanSetCapability { + String SCREENSHOT_QUALITY_OPTION = "screenshotQuality"; + + /** + * Changes the quality of phone display screenshots following + * xctest/xctimagequality Default value is 1. 0 is the highest and + * 2 is the lowest quality. You can also change it via settings + * command. 0 might cause OutOfMemory crash on high-resolution + * devices like iPad Pro. + * + * @param quality Quality value in range 0..2. + * @return self instance for chaining. + */ + default T setScreenshotQuality(int quality) { + return amend(SCREENSHOT_QUALITY_OPTION, quality); + } + + /** + * Get the screenshot quality value. + * + * @return The screenshot quality value. + */ + default Optional getScreenshotQuality() { + return Optional.ofNullable(toInteger(getCapability(SCREENSHOT_QUALITY_OPTION))); + } +} diff --git a/src/main/java/io/appium/java_client/ios/options/wda/SupportsShouldTerminateAppOption.java b/src/main/java/io/appium/java_client/ios/options/wda/SupportsShouldTerminateAppOption.java new file mode 100644 index 000000000..4c92b812f --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/wda/SupportsShouldTerminateAppOption.java @@ -0,0 +1,53 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.appium.java_client.ios.options.wda; + +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 SupportsShouldTerminateAppOption> extends + Capabilities, CanSetCapability { + String SHOULD_TERMINATE_APP_OPTION = "shouldTerminateApp"; + + /** + * Specify if the app should be terminated on session end. + * This capability only has an effect if an application identifier + * has been passed to the test session (either explicitly, + * by setting bundleId, or implicitly, by providing app). + * Default is true unless noReset capability is set to true. + * + * @param value Whether to enforce app termination on session quit. + * @return self instance for chaining. + */ + default T setShouldTerminateApp(boolean value) { + return amend(SHOULD_TERMINATE_APP_OPTION, value); + } + + /** + * Get whether to enforce app termination on session quit. + * + * @return True or false. + */ + default Optional doesTerminateApp() { + return Optional.ofNullable(toSafeBoolean(getCapability(SHOULD_TERMINATE_APP_OPTION))); + } +} diff --git a/src/main/java/io/appium/java_client/ios/options/wda/SupportsShouldUseSingletonTestManagerOption.java b/src/main/java/io/appium/java_client/ios/options/wda/SupportsShouldUseSingletonTestManagerOption.java new file mode 100644 index 000000000..16ee1d2cd --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/wda/SupportsShouldUseSingletonTestManagerOption.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.wda; + +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 SupportsShouldUseSingletonTestManagerOption> extends + Capabilities, CanSetCapability { + String SHOULD_USE_SINGLETON_TEST_MANAGER_OPTION = "shouldUseSingletonTestManager"; + + /** + * Enforce usage of the default proxy for test management within WebDriverAgent. + * + * @return self instance for chaining. + */ + default T shouldUseSingletonTestManager() { + return amend(SHOULD_USE_SINGLETON_TEST_MANAGER_OPTION, true); + } + + /** + * Use default proxy for test management within WebDriverAgent. Setting this to false + * sometimes helps with socket hangup problems. Defaults to true. + * + * @param value Whether to use the default proxy for test management within WebDriverAgent. + * @return self instance for chaining. + */ + default T setShouldUseSingletonTestManager(boolean value) { + return amend(SHOULD_USE_SINGLETON_TEST_MANAGER_OPTION, value); + } + + /** + * Get whether to use the default proxy for test management within WebDriverAgent. + * + * @return True or false. + */ + default Optional doesUseSingletonTestManager() { + return Optional.ofNullable(toSafeBoolean(getCapability(SHOULD_USE_SINGLETON_TEST_MANAGER_OPTION))); + } +} diff --git a/src/main/java/io/appium/java_client/ios/options/wda/SupportsShowXcodeLogOption.java b/src/main/java/io/appium/java_client/ios/options/wda/SupportsShowXcodeLogOption.java new file mode 100644 index 000000000..902b67ced --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/wda/SupportsShowXcodeLogOption.java @@ -0,0 +1,61 @@ +/* + * 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.wda; + +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 SupportsShowXcodeLogOption> extends + Capabilities, CanSetCapability { + String SHOW_XCODE_LOG_OPTION = "showXcodeLog"; + + /** + * Enforce to display the output of the Xcode command used to run the tests + * in Appium logs. + * + * @return self instance for chaining. + */ + default T showXcodeLog() { + return amend(SHOW_XCODE_LOG_OPTION, true); + } + + /** + * Whether to display the output of the Xcode command used to run the tests in + * Appium logs. If this is true, there will be lots of extra logging at startup. + * Defaults to false. + * + * @param value Whether to display the output of the Xcode command used to run the tests. + * @return self instance for chaining. + */ + default T setShowXcodeLog(boolean value) { + return amend(SHOW_XCODE_LOG_OPTION, value); + } + + /** + * Get whether to display the output of the Xcode command used to run the tests. + * + * @return True or false. + */ + default Optional doesShowXcodeLog() { + return Optional.ofNullable(toSafeBoolean(getCapability(SHOW_XCODE_LOG_OPTION))); + } +} diff --git a/src/main/java/io/appium/java_client/ios/options/wda/SupportsSimpleIsVisibleCheckOption.java b/src/main/java/io/appium/java_client/ios/options/wda/SupportsSimpleIsVisibleCheckOption.java new file mode 100644 index 000000000..72bebc33a --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/wda/SupportsSimpleIsVisibleCheckOption.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.wda; + +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 SupportsSimpleIsVisibleCheckOption> extends + Capabilities, CanSetCapability { + String SIMPLE_IS_VISIBLE_CHECK_OPTION = "simpleIsVisibleCheck"; + + /** + * Enforce usage of native methods for determining visibility of elements. + * + * @return self instance for chaining. + */ + default T simpleIsVisibleCheck() { + return amend(SIMPLE_IS_VISIBLE_CHECK_OPTION, true); + } + + /** + * Use native methods for determining visibility of elements. + * In some cases this takes a long time. Setting this capability to false will + * cause the system to use the position and size of elements to make sure they + * are visible on the screen. This can, however, lead to false results in some + * situations. Defaults to false, except iOS 9.3, where it defaults to true. + * + * @param value Whether to use native methods for determining visibility of elements + * @return self instance for chaining. + */ + default T setSimpleIsVisibleCheck(boolean value) { + return amend(SIMPLE_IS_VISIBLE_CHECK_OPTION, value); + } + + /** + * Get whether to use native methods for determining visibility of elements. + * + * @return True or false. + */ + default Optional doesSimpleIsVisibleCheck() { + return Optional.ofNullable(toSafeBoolean(getCapability(SIMPLE_IS_VISIBLE_CHECK_OPTION))); + } +} diff --git a/src/main/java/io/appium/java_client/ios/options/wda/SupportsUpdatedWdaBundleIdOption.java b/src/main/java/io/appium/java_client/ios/options/wda/SupportsUpdatedWdaBundleIdOption.java new file mode 100644 index 000000000..2e4da983f --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/wda/SupportsUpdatedWdaBundleIdOption.java @@ -0,0 +1,48 @@ +/* + * 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.wda; + +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 SupportsUpdatedWdaBundleIdOption> extends + Capabilities, CanSetCapability { + String UPDATED_WDA_BUNDLE_ID_OPTION = "updatedWDABundleId"; + + /** + * Bundle id to update WDA to before building and launching on real devices. + * This bundle id must be associated with a valid provisioning profile. + * + * @param identifier Bundle identifier. + * @return self instance for chaining. + */ + default T setUpdatedWdaBundleId(String identifier) { + return amend(UPDATED_WDA_BUNDLE_ID_OPTION, identifier); + } + + /** + * Get the WDA bundle identifier. + * + * @return Identifier value. + */ + default Optional getUpdatedWdaBundleId() { + return Optional.ofNullable((String) getCapability(UPDATED_WDA_BUNDLE_ID_OPTION)); + } +} diff --git a/src/main/java/io/appium/java_client/ios/options/wda/SupportsUseNativeCachingStrategyOption.java b/src/main/java/io/appium/java_client/ios/options/wda/SupportsUseNativeCachingStrategyOption.java new file mode 100644 index 000000000..10f394aee --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/wda/SupportsUseNativeCachingStrategyOption.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.wda; + +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 SupportsUseNativeCachingStrategyOption> extends + Capabilities, CanSetCapability { + String USE_NATIVE_CACHING_STRATEGY_OPTION = "useNativeCachingStrategy"; + + /** + * Set this capability to false in order to use the custom elements caching + * strategy. This might help to avoid stale element exception on property + * change. By default, the native XCTest cache resolution is used (true) + * for all native locators (e.g. all, but xpath). + * + * @param value Whether to use the native caching strategy. + * @return self instance for chaining. + */ + default T setUseNativeCachingStrategy(boolean value) { + return amend(USE_NATIVE_CACHING_STRATEGY_OPTION, value); + } + + /** + * Get whether to use the native caching strategy. + * + * @return True or false. + */ + default Optional doesUseNativeCachingStrategy() { + return Optional.ofNullable(toSafeBoolean(getCapability(USE_NATIVE_CACHING_STRATEGY_OPTION))); + } +} diff --git a/src/main/java/io/appium/java_client/ios/options/wda/SupportsUseNewWdaOption.java b/src/main/java/io/appium/java_client/ios/options/wda/SupportsUseNewWdaOption.java new file mode 100644 index 000000000..2422c078c --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/wda/SupportsUseNewWdaOption.java @@ -0,0 +1,70 @@ +/* + * 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.wda; + +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 SupportsUseNewWdaOption> extends + Capabilities, CanSetCapability { + String USE_NEW_WDA_OPTION = "useNewWDA"; + + /** + * Enforce uninstall of any existing WebDriverAgent app on the device under test. + * + * @return self instance for chaining. + */ + default T useNewWDA() { + return amend(USE_NEW_WDA_OPTION, true); + } + + /** + * If true, forces uninstall of any existing WebDriverAgent app on device. + * Set it to true if you want to apply different startup options for WebDriverAgent + * for each session. Although, it is only guaranteed to work stable on Simulator. + * Real devices require WebDriverAgent client to run for as long as possible without + * reinstall/restart to avoid issues like + * https://github.com/facebook/WebDriverAgent/issues/507. The false value + * (the default behaviour since driver version 2.35.0) will try to + * detect currently running WDA listener executed by previous testing session(s) + * and reuse it if possible, which is highly recommended for real device testing + * and to speed up suites of multiple tests in general. A new WDA session will be + * triggered at the default URL (http://localhost:8100) if WDA is not listening and + * webDriverAgentUrl capability is not set. The negative/unset value of useNewWDA + * capability has no effect prior to xcuitest driver version 2.35.0. + * + * @param value Whether to force uninstall of any existing WebDriverAgent app on device. + * @return self instance for chaining. + */ + default T setUseNewWDA(boolean value) { + return amend(USE_NEW_WDA_OPTION, value); + } + + /** + * Get whether to uninstall of any existing WebDriverAgent app on the device under test. + * + * @return True or false. + */ + default Optional doesUseNewWDA() { + return Optional.ofNullable(toSafeBoolean(getCapability(USE_NEW_WDA_OPTION))); + } +} diff --git a/src/main/java/io/appium/java_client/ios/options/wda/SupportsUsePrebuiltWdaOption.java b/src/main/java/io/appium/java_client/ios/options/wda/SupportsUsePrebuiltWdaOption.java new file mode 100644 index 000000000..bf4ce84ff --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/wda/SupportsUsePrebuiltWdaOption.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.wda; + +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 SupportsUsePrebuiltWdaOption> extends + Capabilities, CanSetCapability { + String USE_PREBUILT_WDA_OPTION = "usePrebuiltWDA"; + + /** + * Enforce to skip the build phase of running the WDA app. + * + * @return self instance for chaining. + */ + default T usePrebuiltWda() { + return amend(USE_PREBUILT_WDA_OPTION, true); + } + + /** + * Skips the build phase of running the WDA app. Building is then the responsibility + * of the user. Only works for Xcode 8+. Defaults to false. + * + * @param value Whether to skip the build phase of running the WDA app. + * @return self instance for chaining. + */ + default T setUsePrebuiltWda(boolean value) { + return amend(USE_PREBUILT_WDA_OPTION, value); + } + + /** + * Get whether to skip the build phase of running the WDA app. + * + * @return True or false. + */ + default Optional doesUsePrebuiltWda() { + return Optional.ofNullable(toSafeBoolean(getCapability(USE_PREBUILT_WDA_OPTION))); + } +} diff --git a/src/main/java/io/appium/java_client/ios/options/wda/SupportsUseSimpleBuildTestOption.java b/src/main/java/io/appium/java_client/ios/options/wda/SupportsUseSimpleBuildTestOption.java new file mode 100644 index 000000000..8b455e629 --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/wda/SupportsUseSimpleBuildTestOption.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.wda; + +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 SupportsUseSimpleBuildTestOption> extends + Capabilities, CanSetCapability { + String USE_SIMPLE_BUILD_TEST_OPTION = "useSimpleBuildTest"; + + /** + * Enforce usage of simple build test. + * + * @return self instance for chaining. + */ + default T useSimpleBuildTest() { + return amend(USE_SIMPLE_BUILD_TEST_OPTION, true); + } + + /** + * Build with build and run test with test in xcodebuild for all Xcode versions if + * this is true, or build with build-for-testing and run tests with + * test-without-building for over Xcode 8 if this is false. Defaults to false. + * + * @param value Whether to use simple build test. + * @return self instance for chaining. + */ + default T setUseSimpleBuildTest(boolean value) { + return amend(USE_SIMPLE_BUILD_TEST_OPTION, value); + } + + /** + * Get whether to use simple build test. + * + * @return True or false. + */ + default Optional doesUseSimpleBuildTest() { + return Optional.ofNullable(toSafeBoolean(getCapability(USE_SIMPLE_BUILD_TEST_OPTION))); + } +} diff --git a/src/main/java/io/appium/java_client/ios/options/wda/SupportsUseXctestrunFileOption.java b/src/main/java/io/appium/java_client/ios/options/wda/SupportsUseXctestrunFileOption.java new file mode 100644 index 000000000..f29c55a77 --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/wda/SupportsUseXctestrunFileOption.java @@ -0,0 +1,69 @@ +/* + * 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.wda; + +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 SupportsUseXctestrunFileOption> extends + Capabilities, CanSetCapability { + String USE_XCTESTRUN_FILE_OPTION = "useXctestrunFile"; + + /** + * Enforce usage of .xctestrun file to launch WDA. + * + * @return self instance for chaining. + */ + default T useXctestrunFile() { + return amend(USE_XCTESTRUN_FILE_OPTION, true); + } + + /** + * Use Xctestrun file to launch WDA. It will search for such file in bootstrapPath. + * Expected name of file is WebDriverAgentRunner_iphoneos<sdkVersion>-arm64.xctestrun for + * real device and WebDriverAgentRunner_iphonesimulator<sdkVersion>-x86_64.xctestrun for + * simulator. One can do build-for-testing for WebDriverAgent project for simulator and + * real device and then you will see Product Folder like this and you need to copy content + * of this folder at bootstrapPath location. Since this capability expects that you have + * already built WDA project, it neither checks whether you have necessary dependencies to + * build WDA nor will it try to build project. Defaults to false. Tips: Xcodebuild builds for the + * target platform version. We'd recommend you to build with minimal OS version which you'd + * like to run as the original WDA module. e.g. If you build WDA for 12.2, the module cannot + * run on iOS 11.4 because of loading some module error on simulator. A module built with 11.4 + * can work on iOS 12.2. (This is xcodebuild's expected behaviour.) + * + * @param value Whether to use .xctestrun file to launch WDA. + * @return self instance for chaining. + */ + default T setUseXctestrunFile(boolean value) { + return amend(USE_XCTESTRUN_FILE_OPTION, value); + } + + /** + * Get whether to use of .xctestrun file to launch WDA + * + * @return True or false. + */ + default Optional doesUseXctestrunFile() { + return Optional.ofNullable(toSafeBoolean(getCapability(USE_XCTESTRUN_FILE_OPTION))); + } +} diff --git a/src/main/java/io/appium/java_client/ios/options/wda/SupportsWaitForIdleTimeoutOption.java b/src/main/java/io/appium/java_client/ios/options/wda/SupportsWaitForIdleTimeoutOption.java new file mode 100644 index 000000000..0d9ffda35 --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/wda/SupportsWaitForIdleTimeoutOption.java @@ -0,0 +1,58 @@ +/* + * 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.wda; + +import io.appium.java_client.internal.CapabilityHelpers; +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.time.Duration; +import java.util.Optional; + +import static io.appium.java_client.internal.CapabilityHelpers.toDuration; + +public interface SupportsWaitForIdleTimeoutOption> extends + Capabilities, CanSetCapability { + String WAIT_FOR_IDLE_TIMEOUT_OPTION = "waitForIdleTimeout"; + + /** + * The time to wait until the application under test is idling. + * XCTest requires the app's main thread to be idling in order to execute any action on it, + * so WDA might not even start/freeze if the app under test is constantly hogging the main + * thread. The default value is 10 (seconds). Setting it to zero disables idling checks completely + * (not recommended) and has the same effect as setting waitForQuiescence to false. + * Available since Appium 1.20.0. + * + * @param timeout Idle timeout. + * @return self instance for chaining. + */ + default T setWaitForIdleTimeout(Duration timeout) { + return amend(WAIT_FOR_IDLE_TIMEOUT_OPTION, timeout.toMillis() / 1000.0); + } + + /** + * Get the maximum timeout to wait until WDA responds to HTTP requests. + * + * @return Timeout value. + */ + default Optional getWaitForIdleTimeout() { + return Optional.ofNullable(getCapability(WAIT_FOR_IDLE_TIMEOUT_OPTION)) + .map(CapabilityHelpers::toDouble) + .map((d) -> toDuration((long) (d * 1000.0))); + } +} diff --git a/src/main/java/io/appium/java_client/ios/options/wda/SupportsWaitForQuiescenceOption.java b/src/main/java/io/appium/java_client/ios/options/wda/SupportsWaitForQuiescenceOption.java new file mode 100644 index 000000000..9c49e469a --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/wda/SupportsWaitForQuiescenceOption.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.wda; + +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 SupportsWaitForQuiescenceOption> extends + Capabilities, CanSetCapability { + String WAIT_FOR_QUIESCENCE_OPTION = "waitForQuiescence"; + + /** + * It allows to turn on/off waiting for application quiescence in WebDriverAgent, + * while performing queries. The default value is true. You can avoid this kind + * of issues if you turn it off. Consider using waitForIdleTimeout capability + * instead for this purpose since Appium 1.20.0. + * + * @param value Whether to wait for application quiescence. + * @return self instance for chaining. + */ + default T setWaitForQuiescence(boolean value) { + return amend(WAIT_FOR_QUIESCENCE_OPTION, value); + } + + /** + * Get whether to wait for application quiescence. + * + * @return True or false. + */ + default Optional doesWaitForQuiescence() { + return Optional.ofNullable(toSafeBoolean(getCapability(WAIT_FOR_QUIESCENCE_OPTION))); + } +} diff --git a/src/main/java/io/appium/java_client/ios/options/wda/SupportsWdaBaseUrlOption.java b/src/main/java/io/appium/java_client/ios/options/wda/SupportsWdaBaseUrlOption.java new file mode 100644 index 000000000..cc0feb213 --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/wda/SupportsWdaBaseUrlOption.java @@ -0,0 +1,72 @@ +/* + * 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.wda; + +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Optional; + +public interface SupportsWdaBaseUrlOption> extends + Capabilities, CanSetCapability { + String WDA_BASE_URL_OPTION = "wdaBaseUrl"; + + /** + * This value, if specified, will be used as a prefix to build a custom + * WebDriverAgent url. It is different from webDriverAgentUrl, because + * if the latter is set then it expects WebDriverAgent to be already + * listening and skips the building phase. Defaults to http://localhost. + * + * @param url The URL prefix. + * @return self instance for chaining. + */ + default T setWdaBaseUrl(URL url) { + return amend(WDA_BASE_URL_OPTION, url.toString()); + } + + /** + * This value, if specified, will be used as a prefix to build a custom + * WebDriverAgent url. It is different from webDriverAgentUrl, because + * if the latter is set then it expects WebDriverAgent to be already + * listening and skips the building phase. Defaults to http://localhost. + * + * @param url The URL prefix. + * @return self instance for chaining. + */ + default T setWdaBaseUrl(String url) { + return amend(WDA_BASE_URL_OPTION, url); + } + + /** + * Get a prefix to build a custom WebDriverAgent URL. + * + * @return The URL prefix. + */ + default Optional getWdaBaseUrl() { + return Optional.ofNullable(getCapability(WDA_BASE_URL_OPTION)) + .map((v) -> { + try { + return (v instanceof URL) ? (URL) v : new URL(String.valueOf(v)); + } catch (MalformedURLException e) { + throw new IllegalArgumentException(e); + } + }); + } +} diff --git a/src/main/java/io/appium/java_client/ios/options/wda/SupportsWdaConnectionTimeoutOption.java b/src/main/java/io/appium/java_client/ios/options/wda/SupportsWdaConnectionTimeoutOption.java new file mode 100644 index 000000000..8885b8c3e --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/wda/SupportsWdaConnectionTimeoutOption.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.wda; + +import io.appium.java_client.internal.CapabilityHelpers; +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.time.Duration; +import java.util.Optional; + +public interface SupportsWdaConnectionTimeoutOption> extends + Capabilities, CanSetCapability { + String WDA_CONNECTION_TIMEOUT_OPTION = "wdaConnectionTimeout"; + + /** + * Connection timeout to wait for a response from WebDriverAgent. + * Defaults to 240000ms. + * + * @param timeout WDA connection timeout. + * @return self instance for chaining. + */ + default T setWdaConnectionTimeout(Duration timeout) { + return amend(WDA_CONNECTION_TIMEOUT_OPTION, timeout.toMillis()); + } + + /** + * Get the maximum timeout to wait until WDA responds to HTTP requests. + * + * @return Timeout value. + */ + default Optional getWdaConnectionTimeout() { + return Optional.ofNullable( + CapabilityHelpers.toDuration(getCapability(WDA_CONNECTION_TIMEOUT_OPTION)) + ); + } +} diff --git a/src/main/java/io/appium/java_client/ios/options/wda/SupportsWdaEventloopIdleDelayOption.java b/src/main/java/io/appium/java_client/ios/options/wda/SupportsWdaEventloopIdleDelayOption.java new file mode 100644 index 000000000..4d35bb5c4 --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/wda/SupportsWdaEventloopIdleDelayOption.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.wda; + +import io.appium.java_client.internal.CapabilityHelpers; +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.time.Duration; +import java.util.Optional; + +import static io.appium.java_client.internal.CapabilityHelpers.toDuration; + +public interface SupportsWdaEventloopIdleDelayOption> extends + Capabilities, CanSetCapability { + String WDA_EVENTLOOP_IDLE_DELAY_OPTION = "wdaEventloopIdleDelay"; + + /** + * Delays the invocation of -[XCUIApplicationProcess setEventLoopHasIdled:] by the + * duration specified with this capability. This can help quiescence apps + * that fail to do so for no obvious reason (and creating a session fails for + * that reason). This increases the time for session creation + * because -[XCUIApplicationProcess setEventLoopHasIdled:] is called multiple times. + * If you enable this capability start with at least 3 seconds and try increasing it, + * if creating the session still fails. Defaults to 0. + * + * @param duration Idle duration. + * @return self instance for chaining. + */ + default T setWdaEventloopIdleDelay(Duration duration) { + return amend(WDA_EVENTLOOP_IDLE_DELAY_OPTION, duration.toMillis() / 1000.0); + } + + /** + * Get the event loop idle delay. + * + * @return Idle duration. + */ + default Optional getWdaEventloopIdleDelay() { + return Optional.ofNullable(getCapability(WDA_EVENTLOOP_IDLE_DELAY_OPTION)) + .map(CapabilityHelpers::toDouble) + .map((d) -> toDuration((long) (d * 1000.0))); + } +} diff --git a/src/main/java/io/appium/java_client/ios/options/wda/SupportsWdaLaunchTimeoutOption.java b/src/main/java/io/appium/java_client/ios/options/wda/SupportsWdaLaunchTimeoutOption.java new file mode 100644 index 000000000..96ec72521 --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/wda/SupportsWdaLaunchTimeoutOption.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.wda; + +import io.appium.java_client.internal.CapabilityHelpers; +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.time.Duration; +import java.util.Optional; + +public interface SupportsWdaLaunchTimeoutOption> extends + Capabilities, CanSetCapability { + String WDA_LAUNCH_TIMEOUT_OPTION = "wdaLaunchTimeout"; + + /** + * Timeout to wait for WebDriverAgent to be pingable, + * e.g. finishes building. Defaults to 60000ms. + * + * @param timeout Timeout to wait until WDA is listening. + * @return self instance for chaining. + */ + default T setWdaLaunchTimeout(Duration timeout) { + return amend(WDA_LAUNCH_TIMEOUT_OPTION, timeout.toMillis()); + } + + /** + * Get the maximum timeout to wait until WDA is listening. + * + * @return Timeout value. + */ + default Optional getWdaLaunchTimeout() { + return Optional.ofNullable( + CapabilityHelpers.toDuration(getCapability(WDA_LAUNCH_TIMEOUT_OPTION)) + ); + } +} diff --git a/src/main/java/io/appium/java_client/ios/options/wda/SupportsWdaLocalPortOption.java b/src/main/java/io/appium/java_client/ios/options/wda/SupportsWdaLocalPortOption.java new file mode 100644 index 000000000..a011edeac --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/wda/SupportsWdaLocalPortOption.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.wda; + +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.toInteger; + +public interface SupportsWdaLocalPortOption> extends + Capabilities, CanSetCapability { + String WDA_LOCAL_PORT_OPTION = "wdaLocalPort"; + + /** + * This value, if specified, will be used to forward traffic from + * Mac host to real ios devices over USB. + * Default value is the same as the port number used by WDA on + * the device under test (8100). + * + * @param port port number in range 0..65535 + * @return self instance for chaining. + */ + default T setWdaLocalPort(int port) { + return amend(WDA_LOCAL_PORT_OPTION, port); + } + + /** + * Get the local port number where the WDA traffic is being forwarded. + * + * @return The port number. + */ + default Optional getWdaLocalPort() { + return Optional.ofNullable(toInteger(getCapability(WDA_LOCAL_PORT_OPTION))); + } +} diff --git a/src/main/java/io/appium/java_client/ios/options/wda/SupportsWdaStartupRetriesOption.java b/src/main/java/io/appium/java_client/ios/options/wda/SupportsWdaStartupRetriesOption.java new file mode 100644 index 000000000..e69a52d42 --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/wda/SupportsWdaStartupRetriesOption.java @@ -0,0 +1,50 @@ +/* + * 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.wda; + +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.toInteger; + +public interface SupportsWdaStartupRetriesOption> extends + Capabilities, CanSetCapability { + String WDA_STARTUP_RETRIES_OPTION = "wdaStartupRetries"; + + /** + * Number of times to try to build and launch WebDriverAgent onto the device. + * Defaults to 2. + * + * @param count Retries count. + * @return self instance for chaining. + */ + default T setWdaStartupRetries(int count) { + return amend(WDA_STARTUP_RETRIES_OPTION, count); + } + + /** + * Get number of retries before to fail WDA deployment. + * + * @return Retries count. + */ + default Optional getWdaStartupRetries() { + return Optional.ofNullable(toInteger(getCapability(WDA_STARTUP_RETRIES_OPTION))); + } +} diff --git a/src/main/java/io/appium/java_client/ios/options/wda/SupportsWdaStartupRetryIntervalOption.java b/src/main/java/io/appium/java_client/ios/options/wda/SupportsWdaStartupRetryIntervalOption.java new file mode 100644 index 000000000..c1fe04a35 --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/wda/SupportsWdaStartupRetryIntervalOption.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.wda; + +import io.appium.java_client.internal.CapabilityHelpers; +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.time.Duration; +import java.util.Optional; + +public interface SupportsWdaStartupRetryIntervalOption> extends + Capabilities, CanSetCapability { + String WDA_STARTUP_RETRY_INTERVAL_OPTION = "wdaStartupRetryInterval"; + + /** + * Time interval to wait between tries to build and launch WebDriverAgent. + * Defaults to 10000ms. + * + * @param interval Interval value. + * @return self instance for chaining. + */ + default T setWdaStartupRetryInterval(Duration interval) { + return amend(WDA_STARTUP_RETRY_INTERVAL_OPTION, interval.toMillis()); + } + + /** + * Get the interval to wait between tries to build and launch WebDriverAgent. + * + * @return Interval value. + */ + default Optional getWdaStartupRetryInterval() { + return Optional.ofNullable( + CapabilityHelpers.toDuration(getCapability(WDA_STARTUP_RETRY_INTERVAL_OPTION)) + ); + } +} diff --git a/src/main/java/io/appium/java_client/ios/options/wda/SupportsWebDriverAgentUrlOption.java b/src/main/java/io/appium/java_client/ios/options/wda/SupportsWebDriverAgentUrlOption.java new file mode 100644 index 000000000..a8d9953bb --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/wda/SupportsWebDriverAgentUrlOption.java @@ -0,0 +1,68 @@ +/* + * 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.wda; + +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Optional; + +public interface SupportsWebDriverAgentUrlOption> extends + Capabilities, CanSetCapability { + String WEB_DRIVER_AGENT_URL_OPTION = "webDriverAgentUrl"; + + /** + * If provided, Appium will connect to an existing WebDriverAgent + * instance at this URL instead of starting a new one. + * + * @param url The URL where WDA is listening. + * @return self instance for chaining. + */ + default T setWebDriverAgentUrl(URL url) { + return amend(WEB_DRIVER_AGENT_URL_OPTION, url.toString()); + } + + /** + * If provided, Appium will connect to an existing WebDriverAgent + * instance at this URL instead of starting a new one. + * + * @param url The URL where WDA is listening. + * @return self instance for chaining. + */ + default T setWebDriverAgentUrl(String url) { + return amend(WEB_DRIVER_AGENT_URL_OPTION, url); + } + + /** + * Get the WDA URL. + * + * @return The URL where WDA is listening. + */ + default Optional getWebDriverAgentUrl() { + return Optional.ofNullable(getCapability(WEB_DRIVER_AGENT_URL_OPTION)) + .map((v) -> { + try { + return (v instanceof URL) ? (URL) v : new URL(String.valueOf(v)); + } catch (MalformedURLException e) { + throw new IllegalArgumentException(e); + } + }); + } +} diff --git a/src/main/java/io/appium/java_client/ios/options/wda/SupportsXcodeCertificateOptions.java b/src/main/java/io/appium/java_client/ios/options/wda/SupportsXcodeCertificateOptions.java new file mode 100644 index 000000000..d17e1e0e4 --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/wda/SupportsXcodeCertificateOptions.java @@ -0,0 +1,58 @@ +/* + * 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.wda; + +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 SupportsXcodeCertificateOptions> extends + Capabilities, CanSetCapability { + String XCODE_ORG_ID_OPTION = "xcodeOrgId"; + String XCODE_SIGNING_ID_OPTION = "xcodeSigningId"; + String DEFAULT_XCODE_SIGNING_ID = "iPhone Developer"; + + /** + * Provides a signing certificate for WebDriverAgent compilation. + * If signing id is not provided/null then it defaults to "iPhone Developer" + * + * @param cert Certificate credentials. + * @return self instance for chaining. + */ + default T setXcodeCertificate(XcodeCertificate cert) { + String signingId = cert.getXcodeSigningId() == null + ? DEFAULT_XCODE_SIGNING_ID + : cert.getXcodeSigningId(); + return amend(XCODE_ORG_ID_OPTION, cert.getXcodeOrgId()) + .amend(XCODE_SIGNING_ID_OPTION, signingId); + } + + /** + * Get a signing certificate for WebDriverAgent compilation. + * + * @return Certificate value. + */ + default Optional getXcodeCertificate() { + String orgId = (String) getCapability(XCODE_ORG_ID_OPTION); + String signingId = (String) getCapability(XCODE_SIGNING_ID_OPTION); + return orgId == null + ? Optional.empty() + : Optional.of(new XcodeCertificate(orgId, signingId)); + } +} diff --git a/src/main/java/io/appium/java_client/ios/options/wda/XcodeCertificate.java b/src/main/java/io/appium/java_client/ios/options/wda/XcodeCertificate.java new file mode 100644 index 000000000..49d2d4639 --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/options/wda/XcodeCertificate.java @@ -0,0 +1,36 @@ +/* + * 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.wda; + +import lombok.Data; +import lombok.ToString; + +@ToString() +@Data() +public class XcodeCertificate { + private final String xcodeOrgId; + private final String xcodeSigningId; + + public XcodeCertificate(String xcodeOrgId, String xcodeSigningId) { + this.xcodeOrgId = xcodeOrgId; + this.xcodeSigningId = xcodeSigningId; + } + + public XcodeCertificate(String xcodeOrgId) { + this(xcodeOrgId, null); + } +} From a25679b1a7d971393c6d67938111d7b8023c4be8 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Tue, 26 Oct 2021 19:47:27 +0200 Subject: [PATCH 2/2] Address comments --- .../SupportsMjpegScreenshotUrlOption.java | 10 ++---- .../internal/CapabilityHelpers.java | 33 ++++++++++++++++--- .../options/wda/SupportsWdaBaseUrlOption.java | 10 ++---- .../wda/SupportsWebDriverAgentUrlOption.java | 10 ++---- .../wda/SupportsXcodeCertificateOptions.java | 10 +++--- 5 files changed, 38 insertions(+), 35 deletions(-) diff --git a/src/main/java/io/appium/java_client/android/options/mjpeg/SupportsMjpegScreenshotUrlOption.java b/src/main/java/io/appium/java_client/android/options/mjpeg/SupportsMjpegScreenshotUrlOption.java index bb78ed30a..bd8111c94 100644 --- a/src/main/java/io/appium/java_client/android/options/mjpeg/SupportsMjpegScreenshotUrlOption.java +++ b/src/main/java/io/appium/java_client/android/options/mjpeg/SupportsMjpegScreenshotUrlOption.java @@ -16,11 +16,11 @@ package io.appium.java_client.android.options.mjpeg; +import io.appium.java_client.internal.CapabilityHelpers; import io.appium.java_client.remote.options.BaseOptions; import io.appium.java_client.remote.options.CanSetCapability; import org.openqa.selenium.Capabilities; -import java.net.MalformedURLException; import java.net.URL; import java.util.Optional; @@ -59,12 +59,6 @@ default T setMjpegScreenshotUrl(String url) { */ default Optional getMjpegScreenshotUrl() { return Optional.ofNullable(getCapability(MJPEG_SCREENSHOT_URL_OPTION)) - .map((v) -> { - try { - return new URL(String.valueOf(v)); - } catch (MalformedURLException e) { - throw new IllegalArgumentException(e); - } - }); + .map(CapabilityHelpers::toUrl); } } diff --git a/src/main/java/io/appium/java_client/internal/CapabilityHelpers.java b/src/main/java/io/appium/java_client/internal/CapabilityHelpers.java index 86b46bfb0..995385b4b 100644 --- a/src/main/java/io/appium/java_client/internal/CapabilityHelpers.java +++ b/src/main/java/io/appium/java_client/internal/CapabilityHelpers.java @@ -19,6 +19,8 @@ import org.openqa.selenium.Capabilities; import javax.annotation.Nullable; +import java.net.MalformedURLException; +import java.net.URL; import java.time.Duration; import java.util.ArrayList; import java.util.List; @@ -75,8 +77,8 @@ public static Boolean toSafeBoolean(Object value) { * Converts generic capability value to integer. * * @param value The capability value. - * @throws NumberFormatException If the given value cannot be parsed to a valid integer. * @return null is the passed value is null otherwise the converted value. + * @throws NumberFormatException If the given value cannot be parsed to a valid integer. */ @Nullable public static Integer toInteger(Object value) { @@ -93,8 +95,8 @@ public static Integer toInteger(Object value) { * Converts generic capability value to long. * * @param value The capability value. - * @throws NumberFormatException If the given value cannot be parsed to a valid long. * @return null is the passed value is null otherwise the converted value. + * @throws NumberFormatException If the given value cannot be parsed to a valid long. */ @Nullable public static Long toLong(Object value) { @@ -111,8 +113,8 @@ public static Long toLong(Object value) { * Converts generic capability value to double. * * @param value The capability value. - * @throws NumberFormatException If the given value cannot be parsed to a valid long. * @return null is the passed value is null otherwise the converted value. + * @throws NumberFormatException If the given value cannot be parsed to a valid long. */ @Nullable public static Double toDouble(Object value) { @@ -130,8 +132,8 @@ public static Double toDouble(Object value) { * measured in milliseconds. * * @param value The capability value. - * @throws NumberFormatException If the given value cannot be parsed to a valid number. * @return null is the passed value is null otherwise the converted value. + * @throws NumberFormatException If the given value cannot be parsed to a valid number. */ @Nullable public static Duration toDuration(Object value) { @@ -143,8 +145,8 @@ public static Duration toDuration(Object value) { * * @param value The capability value. * @param converter Converts the numeric value to a Duration instance. - * @throws NumberFormatException If the given value cannot be parsed to a valid number. * @return null is the passed value is null otherwise the converted value. + * @throws NumberFormatException If the given value cannot be parsed to a valid number. */ @Nullable public static Duration toDuration(Object value, @@ -152,4 +154,25 @@ public static Duration toDuration(Object value, Long v = toLong(value); return v == null ? null : converter.apply(v); } + + /** + * Converts generic capability value to a url. + * + * @param value The capability value. + * @throws IllegalArgumentException If the given value cannot be parsed to a valid url. + * @return null is the passed value is null otherwise the converted value. + */ + @Nullable + public static URL toUrl(Object value) { + if (value == null) { + return null; + } + try { + return (value instanceof URL) + ? (URL) value : + new URL(String.valueOf(value)); + } catch (MalformedURLException e) { + throw new IllegalArgumentException(e); + } + } } diff --git a/src/main/java/io/appium/java_client/ios/options/wda/SupportsWdaBaseUrlOption.java b/src/main/java/io/appium/java_client/ios/options/wda/SupportsWdaBaseUrlOption.java index cc0feb213..2404aa5ef 100644 --- a/src/main/java/io/appium/java_client/ios/options/wda/SupportsWdaBaseUrlOption.java +++ b/src/main/java/io/appium/java_client/ios/options/wda/SupportsWdaBaseUrlOption.java @@ -16,11 +16,11 @@ package io.appium.java_client.ios.options.wda; +import io.appium.java_client.internal.CapabilityHelpers; import io.appium.java_client.remote.options.BaseOptions; import io.appium.java_client.remote.options.CanSetCapability; import org.openqa.selenium.Capabilities; -import java.net.MalformedURLException; import java.net.URL; import java.util.Optional; @@ -61,12 +61,6 @@ default T setWdaBaseUrl(String url) { */ default Optional getWdaBaseUrl() { return Optional.ofNullable(getCapability(WDA_BASE_URL_OPTION)) - .map((v) -> { - try { - return (v instanceof URL) ? (URL) v : new URL(String.valueOf(v)); - } catch (MalformedURLException e) { - throw new IllegalArgumentException(e); - } - }); + .map(CapabilityHelpers::toUrl); } } diff --git a/src/main/java/io/appium/java_client/ios/options/wda/SupportsWebDriverAgentUrlOption.java b/src/main/java/io/appium/java_client/ios/options/wda/SupportsWebDriverAgentUrlOption.java index a8d9953bb..a985e280b 100644 --- a/src/main/java/io/appium/java_client/ios/options/wda/SupportsWebDriverAgentUrlOption.java +++ b/src/main/java/io/appium/java_client/ios/options/wda/SupportsWebDriverAgentUrlOption.java @@ -16,11 +16,11 @@ package io.appium.java_client.ios.options.wda; +import io.appium.java_client.internal.CapabilityHelpers; import io.appium.java_client.remote.options.BaseOptions; import io.appium.java_client.remote.options.CanSetCapability; import org.openqa.selenium.Capabilities; -import java.net.MalformedURLException; import java.net.URL; import java.util.Optional; @@ -57,12 +57,6 @@ default T setWebDriverAgentUrl(String url) { */ default Optional getWebDriverAgentUrl() { return Optional.ofNullable(getCapability(WEB_DRIVER_AGENT_URL_OPTION)) - .map((v) -> { - try { - return (v instanceof URL) ? (URL) v : new URL(String.valueOf(v)); - } catch (MalformedURLException e) { - throw new IllegalArgumentException(e); - } - }); + .map(CapabilityHelpers::toUrl); } } diff --git a/src/main/java/io/appium/java_client/ios/options/wda/SupportsXcodeCertificateOptions.java b/src/main/java/io/appium/java_client/ios/options/wda/SupportsXcodeCertificateOptions.java index d17e1e0e4..fcecbab8c 100644 --- a/src/main/java/io/appium/java_client/ios/options/wda/SupportsXcodeCertificateOptions.java +++ b/src/main/java/io/appium/java_client/ios/options/wda/SupportsXcodeCertificateOptions.java @@ -36,9 +36,8 @@ public interface SupportsXcodeCertificateOptions> exten * @return self instance for chaining. */ default T setXcodeCertificate(XcodeCertificate cert) { - String signingId = cert.getXcodeSigningId() == null - ? DEFAULT_XCODE_SIGNING_ID - : cert.getXcodeSigningId(); + String signingId = Optional.ofNullable(cert.getXcodeSigningId()) + .orElse(DEFAULT_XCODE_SIGNING_ID); return amend(XCODE_ORG_ID_OPTION, cert.getXcodeOrgId()) .amend(XCODE_SIGNING_ID_OPTION, signingId); } @@ -51,8 +50,7 @@ default T setXcodeCertificate(XcodeCertificate cert) { default Optional getXcodeCertificate() { String orgId = (String) getCapability(XCODE_ORG_ID_OPTION); String signingId = (String) getCapability(XCODE_SIGNING_ID_OPTION); - return orgId == null - ? Optional.empty() - : Optional.of(new XcodeCertificate(orgId, signingId)); + return Optional.ofNullable(orgId) + .map((x) -> new XcodeCertificate(orgId, signingId)); } }